1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| using namespace std; struct Node { int left; int right; __int64 value;//这里注意 int add;//标记,提高时间效率 }tree[300000]; int num[100010]; __int64 build(int l,int r,int idx) { int mid; tree[idx].left=l; tree[idx].right=r; tree[idx].add=0; if(l==r) { return tree[idx].value=num[l];//叶子节点值 } mid=(l+r)/2; return tree[idx].value=build(l,mid,ll(idx))+build(mid+1,r,rr(idx));//又忘了加1,囧事 } __int64 query(int l,int r,int idx) { int mid; if(tree[idx].left==l&&tree[idx].right==r) return tree[idx].value;// if(tree[idx].add)//接着更新,这里易错 { tree[ll(idx)].value+=(__int64)(tree[ll(idx)].right-tree[ll(idx)].left+1)*tree[idx].add; tree[rr(idx)].value+=(__int64)(tree[rr(idx)].right-tree[rr(idx)].left+1)*tree[idx].add; tree[ll(idx)].add+=tree[idx].add; tree[rr(idx)].add+=tree[idx].add; tree[idx].add=0; } mid=(tree[idx].left+tree[idx].right)/2; if(r<=mid) return query(l,r,ll(idx)); else if(l>mid) return query(l,r,rr(idx)); else return query(l,mid,ll(idx))+query(mid+1,r,rr(idx));//一直忘记+1; } void update(int l,int r,int a,int idx) { int mid; if(tree[idx].left>=l&&tree[idx].right<=r) { tree[idx].value+=(__int64)(tree[idx].right-tree[idx].left+1)*a; tree[idx].add+=a; return ;//以为这里没有更新孩子节点,所以在query中还有更新的环节 } if(tree[idx].add)//接着更新,这里易错 { tree[ll(idx)].value+=(__int64)(tree[ll(idx)].right-tree[ll(idx)].left+1)*tree[idx].add; tree[rr(idx)].value+=(__int64)(tree[rr(idx)].right-tree[rr(idx)].left+1)*tree[idx].add; tree[ll(idx)].add+=tree[idx].add; tree[rr(idx)].add+=tree[idx].add; tree[idx].add=0; } mid=(tree[idx].left+tree[idx].right)/2; if(l<=mid) update(l,r,a,ll(idx));//只要有一个就得更新 if(r>mid) update(l,r,a,rr(idx)); tree[idx].value=tree[ll(idx)].value+tree[rr(idx)].value; } int main() { int i,m,n,l,r; int a; char ch[10]; while(scanf("%d%d",&n,&m)!=EOF) { for(i=1;i<=n;i++)//这里下标从1开始 scanf("%d",&num[i]); build(1,n,1); while(m--) { getchar(); cin>>ch; //scanf("%s",ch); if(ch[0]=='Q') { scanf("%d%d",&l,&r); printf("%I64d\n",query(l,r,1));//防止越界 } else { scanf("%d%d%d",&l,&r,&a); update(l,r,a,1); } } } return 0; }
|