题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027
题意:给定两种操作,查询(求出区间内的和),更新(区间内每个值都开根号,取整数)
题目给出所有数字之和小于263,所以最大的数最多7次也就变成1。所以在更新的时候加个判断条件,提前结束。
然后这道题目还有个坑,L有可能比R大,需要交换一下,(╬▔皿▔) 。
1 #include <cstdio> 2 #include <algorithm> 3 #include <cmath> 4 using namespace std; 5 6 typedef long long LL; 7 const int MAX=100011; 8 9 LL ans; 10 struct Tree 11 { 12 LL l,r; 13 LL sum; 14 }; 15 Tree tree[MAX*4]; 16 17 void pushup(LL x) 18 { 19 LL tmp=2*x; 20 tree[x].sum=tree[tmp].sum+tree[tmp+1].sum; 21 } 22 23 void build(int l,int r,int x) 24 { 25 tree[x].l=l; 26 tree[x].r=r; 27 if(l==r) 28 { 29 scanf("%lld",&tree[x].sum); 30 return ; 31 } 32 LL tmp=x<<1; 33 LL mid=(l+r)>>1; 34 build(l,mid,tmp); 35 build(mid+1,r,tmp+1); 36 pushup(x); 37 } 38 39 40 void update(LL l,LL r,LL x) 41 { 42 if(r<tree[x].l||l>tree[x].r) return ; 43 if(tree[x].l==tree[x].r) 44 { 45 tree[x].sum=sqrt(tree[x].sum); 46 return ; 47 } 48 if(l<=tree[x].l&&r>=tree[x].r&&tree[x].sum==tree[x].r-tree[x].l+1) return; 49 LL tmp=x<<1; 50 update(l,r,tmp); 51 update(l,r,tmp+1); 52 pushup(x); 53 } 54 55 56 void query(LL l,LL r,LL x) 57 { 58 if(r<tree[x].l||l>tree[x].r) return ; 59 if(l<=tree[x].l&&r>=tree[x].r) 60 { 61 ans+=tree[x].sum; 62 return ; 63 } 64 LL tmp=x<<1; 65 LL mid=(tree[x].l+tree[x].r)>>1; 66 if(r<=mid) query(l,r,tmp); 67 else if(l>mid) query(l,r,tmp+1); 68 else 69 { 70 query(l,mid,tmp); 71 query(mid+1,r,tmp+1); 72 } 73 } 74 75 int main(){ 76 LL n,m,cas=1; 77 while(scanf("%lld",&n)!=EOF){ 78 LL T,X,Y; 79 build(1,n,1); 80 scanf("%lld",&m); 81 printf("Case #%lld:\n",cas++); 82 for(int i=1;i<=m;i++){ 83 scanf("%lld %lld %lld",&T,&X,&Y); 84 if(X>Y) swap(X,Y); 85 if(T==1){ 86 ans=0; 87 query(X,Y,1); 88 printf("%lld\n",ans); 89 } 90 else if(T==0){ 91 update(X,Y,1); 92 } 93 } 94 printf("\n"); 95 } 96 return 0; 97 }
时间: 2024-10-21 01:04:01