1 10 1 2 3 4 5 6 7 8 9 10 Query 1 3 Add 3 6 Query 2 7 Sub 10 2 Add 6 3 Query 3 10 End
Case 1: 6 33 59
Eddy
很明显的一道线段树的题,当然树状数组也可以做。单点更新加求区间和,上代码
#include<stdio.h> #include<algorithm> #define N 50005 using namespace std; struct Node { int left,right; int sum; }tree[3*N]; int num[N],sum; void create(int root, int left, int right) { tree[root].left = left; tree[root].right = right; if(left==right) { tree[root].sum = num[left]; return ; } int mid = (left + right)>>1; create(root<<1, left, mid); create(root<<1|1, mid+1, right); tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum; } void update(int root, int pos, int val) { if(tree[root].left==pos&&tree[root].right==pos) { tree[root].sum += val; return ; } int mid = (tree[root].left + tree[root].right)>>1; if(pos <= mid) update(root<<1, pos, val); else update(root<<1|1, pos, val); tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum; } void query(int root, int left, int right) { if(tree[root].left==left&&tree[root].right==right) { sum += tree[root].sum; return ; } int mid = (tree[root].left + tree[root].right)>>1; if(right <= mid) query(root<<1, left, right); else if(left > mid) query(root<<1|1, left, right); else { query(root<<1, left, mid); query(root<<1|1, mid+1, right); } } int main() { int T,n,cnt = 0; char q[10]; scanf("%d", &T); while(T--) { scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d", &num[i]); create(1, 1, n); printf("Case %d:\n", ++cnt); while(~scanf("%s", q)) { if(q[0]=='E')break; sum = 0; int i,j; scanf("%d%d", &i,&j); if(q[0]=='A') update(1, i, j); else if(q[0]=='S') update(1, i, -j); else { query(1, i, j); printf("%d\n", sum); } } } return 0; }