简单线段树,开根号开几次这个数就为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"); } }