注意到当一个数开方到1后就不再变了,每个数开方次数不会太多,所以进行更新时如果该区间的数字都是1了就直接return
#include <stdio.h> #include <string.h> #include <math.h> #define maxn 100100 __int64 sum[4*maxn]; void build(int l,int r,int o) { if(l==r) { scanf("%I64d",&sum[o]); return ; } int m=(l+r)/2; build(l,m,o*2); build(m+1,r,o*2+1); sum[o]=sum[o*2]+sum[o*2+1]; } void update(int ql,int qr,int l,int r,int o) { if(sum[o]==r-l+1) return ; if(l==r) { sum[o]=(__int64)sqrt(1.0*sum[o]); return ; } int m=(l+r)/2; if(ql<=m) update(ql,qr,l,m,o*2); if(qr>m) update(ql,qr,m+1,r,o*2+1); sum[o]=sum[o*2]+sum[o*2+1]; } __int64 query(int ql,int qr,int l,int r,int o) { if(ql<=l&&r<=qr) return sum[o]; __int64 ans=0; int m=(l+r)/2; if(ql<=m) ans+=query(ql,qr,l,m,o*2); if(qr>m) ans+=query(ql,qr,m+1,r,o*2+1); return ans; } int main() { int n; int T; int x,y,z; int num=0; while(scanf("%d",&n)!=EOF) { num++; build(1,n,1); printf("Case #%d: ",num); scanf("%d",&T); while(T--) { int temp; scanf("%d%d%d",&x,&y,&z); if(y>z) {temp=y;y=z;z=temp;} if(x==0) update(y,z,1,n,1); if(x==1) printf("%I64d ",query(y,z,1,n,1)); } puts(""); } return 0; }