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
线段树的题目,也是第一次做线段树;当然也可以用树状数组:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAX = 50000; struct ss { int left, right, sum; }Segtree[MAX*4]; int T, N, x, y, kase = 1, a[MAX], ans; char q[10]; void Build(int node, int l, int r)//建树 { Segtree[node].left = l; Segtree[node].right = r; if(r == l) { scanf("%d", &Segtree[node].sum); return; } Build(node*2, l, (l+r)/2); Build(node*2+1, (l+r)/2+1, r); Segtree[node].sum = Segtree[node*2].sum + Segtree[node*2+1].sum; } void Query(int node, int l, int r)//查询 { if(l > Segtree[node].right || r < Segtree[node].left) return; if(l <= Segtree[node].left && r >= Segtree[node].right) { ans += Segtree[node].sum; return; } Query(node*2, l, r); Query(node*2+1, l, r); } void Change(int node, int num, int mark)//修改 { if(num < Segtree[node].left || num > Segtree[node].right) return; if(Segtree[node].left == Segtree[node].right) { Segtree[node].sum += mark; return; } Change(node*2, num, mark); Change(node*2+1, num, mark); Segtree[node].sum = Segtree[node*2].sum + Segtree[node*2+1].sum; } int main() { scanf("%d", &T); while(T--) { printf("Case %d:\n", kase++); scanf("%d", &N); Build(1, 1, N); while(scanf("%s", q) && q[0] != 'E') { scanf("%d %d", &x, &y); if(q[0] == 'Q') { ans = 0; Query(1, x, y); cout << ans << endl; } else if(q[0] == 'A') Change(1, x, y); else Change(1, x, -y); } } return 0; }
树状数组做法如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAX = 50010; int tree[MAX]; int T, N, k, x, y, kase = 1; char s[10]; void Insert(int pos, int num) { while(pos <= N) { tree[pos] += num; pos += pos&(-pos); } } int Query(int posx, int posy) { int sumx = 0, sumy = 0; while(posx > 0) { sumx += tree[posx]; posx -= posx&(-posx); } while(posy > 0) { sumy += tree[posy]; posy -= posy&(-posy); } return sumy - sumx; } int main() { scanf("%d", &T); while(T--) { memset(tree, 0, sizeof(tree)); scanf("%d", &N); for(int i =1;i <= N; ++i) { scanf("%d", &k); Insert(i, k); } printf("Case %d:\n", kase++); while(scanf("%s", s) && s[0] != 'E') { scanf("%d %d", &x, &y); if(s[0] == 'Q') cout << Query(x-1, y) << endl; else if(s[0] == 'A') Insert(x, y); else Insert(x, -y); } } return 0; }