4027 Can you answer these queries?
两种操作:
1 x y 把[x y]区间中的数变为原来数值的根号(取整)
0 x y 求[x y]区间和
分析:线段树 区间更新+区间求和 可增加一个标记表示该位置上的数位1或0 因为1 或0 开根号还是本身不用更新
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #define maxlen 100010 7 typedef long long ll; 8 using namespace std; 9 struct node 10 { 11 int l,r; 12 ll sum; 13 bool flag; 14 }tree[maxlen*4]; 15 void build(int l,int r,int rt) 16 { 17 tree[rt].l=l; 18 tree[rt].r=r; 19 tree[rt].sum=0; 20 tree[rt].flag=false; 21 if(l==r)return ; 22 int m = (l+r)/2; 23 build(l,m,rt*2); 24 build(m+1,r,rt*2+1); 25 } 26 void Insert(int pos, ll num,int rt) 27 { 28 if(tree[rt].l==tree[rt].r) 29 { 30 tree[rt].sum=num; 31 return ; 32 } 33 int m = (tree[rt].l+tree[rt].r)/2; 34 if(pos<=m)Insert(pos,num,rt*2); 35 else Insert(pos,num,rt*2+1); 36 tree[rt].sum = tree[rt*2].sum+tree[rt*2+1].sum; 37 } 38 void Update(int l ,int r ,int rt) 39 { 40 if(tree[rt].flag||tree[rt].r<l||tree[rt].l>r)return ; 41 if(tree[rt].l==tree[rt].r) 42 { 43 tree[rt].sum = ll(sqrt(tree[rt].sum)); 44 if(tree[rt].sum<=1)tree[rt].flag=true; 45 return ; 46 } 47 Update(l,r,rt*2); 48 Update(l,r,rt*2+1); 49 tree[rt].sum = tree[rt*2].sum+tree[rt*2+1].sum; 50 tree[rt].flag = tree[rt*2].flag&&tree[rt*2+1].flag; 51 } 52 ll query(int l,int r,int rt) 53 { 54 if(tree[rt].r<l||tree[rt].l>r)return 0; 55 if(tree[rt].l>=l&&tree[rt].r<=r)return tree[rt].sum; 56 return query(l,r,rt*2)+query(l,r,rt*2+1); 57 } 58 ll num[maxlen]; 59 int main () 60 { 61 int n,m,Case=1; 62 while(scanf("%d",&n)!=EOF) 63 { 64 build(1,n,1); 65 for(int i=1;i<=n;++i) 66 { 67 scanf("%I64d",&num[i]); 68 Insert(i,num[i],1); 69 } 70 scanf("%d",&m); 71 printf("Case #%d: ",Case++); 72 for(int i=0;i<m;++i) 73 { 74 int cmd,x,y; 75 scanf("%d%d%d",&cmd,&x,&y); 76 if(x>y)swap(x,y); 77 if(cmd==0)Update(x,y,1); 78 else printf("%I64d ",query(x,y,1)); 79 } 80 printf(" "); 81 } 82 }