HDU 4027 Can you answer these queries?【成段更新】

题意: 有n 个敌人,告诉每个船的初始血量,攻击时告诉你一个区间,这个区间里面的船每个船的血变成以前的根号倍,询问的时候输出每个区间的总和。

分析:注意的地方就是当这个区间的和等于区间长度时,就不用再更新。

View Code
#include<stdio.h>
#include<string.h>
#include<math.h>
const int maxn=111111;
__int64 sum[maxn<<2];
void creat(int l,int r,int rt)
{
    if(l==r)
    {
        scanf("%I64d",&sum[rt]);
        return;
    }
    int m=(l+r)>>1;
    creat(l,m,rt<<1);
    creat(m+1,r,rt<<1|1);
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int L,int R,int l,int r,int rt)
{
    if(sum[rt]==(__int64)(r-l+1))
    return;
    if(l==r)
    {
        sum[rt]=(long long)sqrt((double)sum[rt]);
        return;
    }
    int m=(l+r)>>1;
    if(L<=m) update(L,R,l,m,rt<<1);
    if(R>m)  update(L,R,m+1,r,rt<<1|1);
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
__int64 query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
        return sum[rt];
    __int64 res=0;
    int m=(l+r)>>1;
    if(L<=m) res+=query(L,R,l,m,rt<<1);
    if(R>m)  res+=query(L,R,m+1,r,rt<<1|1);
    return res;
}
int main()
{
   int i,n,Q,a,b,T,ca=1,tmp;
   while(scanf("%d",&n)!=EOF)
   {
       creat(1,n,1);
       scanf("%d",&Q);
       printf("Case #%d:\n",ca++);
       while(Q--)
       {
           scanf("%d%d%d",&T,&a,&b);
            if(a >b)a^=b^=a^=b;
           if(T)
               printf("%I64d\n",query(a,b,1,n,1));
           else   update(a,b,1,n,1);
       }
       printf("\n");
   }
    return 0;
}
posted @ 2012-05-07 20:52  'wind  阅读(222)  评论(0)    收藏  举报