HDU4027 Can you answer these queries? [线段树]

  简单线段树,开根号开几次这个数就为1了,之后再对其开根号就没有意义了。当一个区间全部为0或者1时就没有必要再去跟新这个区间了。

  

#include <string.h>
#include <stdio.h>
#include <math.h>
#define lson l,m,p<<1
#define rson m+1,r,p<<1|1
#define calm (l+r)>>1
#define MAXN 100005

typedef __int64 LL;
int n,q,cas=1,tu,tv,tq;
LL sum[MAXN<<2],x[MAXN];
int root[MAXN<<2];
void pushup(int p){
    root[p]=root[p<<1]+root[p<<1|1];
    sum[p]=sum[p<<1]+sum[p<<1|1];
}
void init(int l,int r,int p){
    if(l==r){
        sum[p]=x[l];
        root[p]=(x[l]>1?1:0);
        return;
    }
    int m=calm;
    init(lson);init(rson);
    pushup(p);
}
void update(int L,int R,int l,int r,int p){
    if(root[p]==0)return;
    if(l==r){
        sum[p]=(LL)sqrt((double)(sum[p]+0.5));
        root[p]=(sum[p]>1?1:0);
        return;
    }
    int m=calm;
    if(L<=m)update(L,R,lson);
    if(R>m)update(L,R,rson);
    pushup(p);
}
LL query(int L,int R,int l,int r,int p){
    if(L<=l&&r<=R)return sum[p];
    LL tmp=0;
    int m=calm;
    if(L<=m)tmp+=query(L,R,lson);
    if(R>m)tmp+=query(L,R,rson);
    return tmp;
}
int main(){
    freopen("test.in","r",stdin);
    while(scanf("%d",&n)!=EOF){
        for(int i=1;i<=n;i++)scanf("%I64d",&x[i]);
        init(1,n,1);
        scanf("%d",&q);
        printf("Case #%d:\n",cas++);
        while(q--){
            scanf("%d%d%d",&tq,&tu,&tv);
            if(tu>tv)tu^=tv,tv=tu^tv,tu=tu^tv;
            if(tq==0){
                update(tu,tv,1,n,1);
            }else{
                printf("%I64d\n",query(tu,tv,1,n,1));
            }
        }
        printf("\n");
    }
}
原文地址:https://www.cnblogs.com/swm8023/p/2659384.html