- 线段树(kuangbin本题链接)
#include "bits/stdc++.h" using namespace std; const int MAXN = 50010; struct Node { int l, r; int sum; } segTree[MAXN * 4]; void build(int i, int l, int r) { segTree[i].l = l; segTree[i].r = r; if (l == r) { scanf("%d", &segTree[i].sum); return; } int mid = l + r >> 1; build(i << 1, l, mid); build(i << 1 | 1, mid + 1, r); segTree[i].sum = segTree[i << 1].sum + segTree[i << 1 | 1].sum; } void add(int i, int k, int v) { segTree[i].sum += v; if (segTree[i].l == segTree[i].r) return; int mid = segTree[i].l + segTree[i].r >> 1; if (k <= mid) add(i << 1, k, v); else add(i << 1 | 1, k, v); } int query(int i, int l, int r) { if (segTree[i].l == l && segTree[i].r == r) return segTree[i].sum; int mid = segTree[i].l + segTree[i].r >> 1; if (r <= mid) return query(i << 1, l, r); else if (l > mid) return query(i << 1 | 1, l, r); else return query(i << 1, l, mid) + query(i << 1 | 1, mid + 1, r); } int main() { int t, n; char op[10]; scanf("%d", &t); for (int ca = 1; ca <= t; ca++) { printf("Case %d:\n", ca); scanf("%d", &n); build(1, 1, n); int x, y; while (scanf("%s", op) && op[0] != 'E') { scanf("%d%d", &x, &y); if (op[0] == 'Q') printf("%d\n", query(1, x, y)); else if (op[0] == 'A') add(1, x, y); else add(1, x, -y); } } return 0; }
修改自2019年6月6日,删除了原先的线段树代码,原先不喜欢用结构体定义线段树的节点,现在感觉到用结构体代码清晰一点。模仿的kuangbin模板。
- 树状数组
#include"cstdio" #include"cstring" using namespace std; int tree[50005],N,x,y; //用来求x二进制码从右往左数第一个1所在位的值 int lowbit(int x){ return x&-x; } void Add(int x){ while(x<=N){ tree[x]+=y; x+=lowbit(x); } } int Query(int x){ int ans=0; while(x){ ans+=tree[x]; x-=lowbit(x); } return ans; } int main(){ int T;char s[10]; scanf("%d",&T); for(int k=1;k<=T;k++){ memset(tree,0,sizeof(tree)); scanf("%d",&N); for(int i=1;i<=N;i++){ scanf("%d",&y); Add(i); } printf("Case %d:\n",k); while(scanf("%s",s)&&s[0]!='E'){ scanf("%d%d",&x,&y); if(s[0]=='Q')printf("%d\n",Query(y)-Query(x-1)); else { if(s[0]=='S')y=-y; Add(x); } } } return 0; }