线段树区间开方。。重写一遍就AC了,神马情况。。。。
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(i=l;i<=r;i++) 3 #define dec(i,l,r) for(i=l;i>=r;i--) 4 #define inf 1e9 5 #define ll long long 6 #define NM 100000+5 7 #define mem(a) memset(a,0,sizeof(a)) 8 using namespace std; 9 int read(){ 10 int x=0,f=1;char ch=getchar(); 11 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 12 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 13 return x*f; 14 } 15 struct info{ 16 ll s; 17 int z; 18 info(int x=0):s((ll)x),z(x<=1){} 19 }T[3*NM]; 20 info operator+(const info&x,const info&y){ 21 info f; 22 f.s=x.s+y.s; 23 f.z=x.z&&y.z; 24 return f; 25 } 26 int n,m,i,x,t,y; 27 void build(int i,int x,int y){ 28 int t=x+y>>1; 29 if(x==y){ 30 T[i]=info(read()); 31 return; 32 } 33 build(i<<1,x,t);build(i<<1|1,t+1,y); 34 T[i]=T[i<<1]+T[i<<1|1]; 35 } 36 void cut(int i,int x,int y,int a,int b){ 37 int t=x+y>>1; 38 if(b<x||y<a||T[i].z)return; 39 if(x==y){ 40 T[i].s=(ll)sqrt(T[i].s); 41 T[i].z=T[i].s<=1; 42 return; 43 } 44 cut(i<<1,x,t,a,b);cut(i<<1|1,t+1,y,a,b); 45 T[i]=T[i<<1]+T[i<<1|1]; 46 } 47 ll sum(int i,int x,int y,int a,int b){ 48 int t=x+y>>1; 49 if(b<x||y<a)return 0; 50 if(a<=x&&y<=b)return T[i].s; 51 return sum(i<<1,x,t,a,b)+sum(i<<1|1,t+1,y,a,b); 52 } 53 int main(){ 54 n=read(); 55 build(1,1,n); 56 m=read(); 57 inc(i,1,m){ 58 t=read();x=read();y=read(); 59 if(t==1)printf("%lld\n",sum(1,1,n,x,y)); 60 else cut(1,1,n,x,y); 61 } 62 }