首页 > 代码库 > HDU 4027 Can you answer these queries? (线段树+区间点修改)

HDU 4027 Can you answer these queries? (线段树+区间点修改)



题意:给你 n 个数,m个询问(c,x,y)

c==0 把x,y区间的值变为原来的平方根(向下取整)

c==1 计算x,y区间的和。


利用1的开方永远为1剪枝。。



#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<string>
//#include<map>
#include<cmath>
#include<iostream>
#include <queue>
#include <stack>
#include<algorithm>
#include<set>
using namespace std;
#define inf 1e8
#define eps 1e-8
#define ll __int64
#define maxn 100001
#define mol 100007
struct node
{
   int left,right;
   int flag;//标记当前节点sum是否为1
   ll sum;
}tree[maxn*3];
ll a[maxn];
void build(int id,int l,int r)
{
    
    tree[id].left =l;tree[id].right =r;tree[id].sum =0;tree[id].flag=0;
        
    if(l==r)
    {
        if(a[l]==1)
            tree[id].flag=1;
        tree[id].sum=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(id*2,l,mid);
    build(id*2+1,mid+1,r);
    tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
    if(tree[id*2].flag==1&&tree[id*2+1].flag==1)
        tree[id].flag=1;
}
ll query(int id,int l,int r)
{
    if(tree[id].flag==1) return r-l+1;//节点id区间都为1,返回区间长度
   if(l==tree[id].left&&r ==tree[id].right )
       return tree[id].sum ;
   if(tree[id].left >r||tree[id].right<l) return 0;
   int mid=(tree[id].left +tree[id].right )/2;
   if(mid>=r)
   return query(id*2,l,r);
   else if(mid+1<=l) return query(id*2+1,l,r);
   else return query(id*2,l,mid)+query(id*2+1,mid+1,r);
}
void update(int id ,int l,int r)
{
    if(tree[id].flag==1)//节点id区间都为1,则不需要继续开方
        return ;
    if(tree[id].left==tree[id].right)
     {
         tree[id].sum=(ll)sqrt(tree[id].sum*1.0);
         if(tree[id].sum==1)
             tree[id].flag=1;
         return ;
     }
    else
    {
         int mid=(tree[id].left+tree[id].right)/2;
         if(mid>=r)
             update(id*2,l,r);  
         else if(mid<l)
            update(id*2+1,l,r);
         else 
         {
            update(id*2,l,mid);  
            update(id*2+1,mid+1,r);  
         }
    }
     tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
     if(tree[id*2].flag==1&&tree[id*2+1].flag==1)
         tree[id].flag=1;
}
int main()
{
    int i,j;
    int n,m,C=1;
    while(~scanf("%d",&n))
    {
        for(i=1;i<=n;i++)
            scanf("%I64d",&a[i]);
        build(1,1,n);
        scanf("%d",&m);
        int c,x,y;
        printf("Case #%d:\n",C++);
        for(i=0;i<m;i++)
        {
           scanf("%d%d%d",&c,&x,&y);
           if(x>y) swap(x,y);
           if(c==0)
           {
                update(1,x,y);
           }
           else 
           {
                printf("%I64d\n",query(1,x,y));
           }
        }
        printf("\n");
    }
    return 0;
}