树状数组做法: #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <sstream> #include <map> #include <set> #include <queue> #include <stdlib.h> using namespace std; typedef long long ll; int a[50005]; //原数组 int c[50005]; //树状数组 void init() //初始化a,c数组 { memset(a, 0, sizeof(a)); memset(c, 0, sizeof(c)); } int n; //一共多少个兵营 int lowbit(int x) { return x&(-x); //x&(-x), //x为0时,结果为0; //x为奇数时,结果为1; //x为偶数时,结果为x中2的最大次方的因子。 } void updata(int i,int k) //在i位置加上k,并更新数组的数据 { while(i<=n) { c[i]+=k; i+=lowbit(i); } } int getsum(int i) //求前i项的和 { int ans=0; while(i>0) { ans+=c[i]; i-=lowbit(i); } return ans; } int main() { int t; cin >> t; for (int I=1;I<=t;I++) { cout << "Case " << I << ":" << endl; init(); cin >> n; for (int i=1;i<=n;i++) { cin >> a[i]; updata(i,a[i]); } string s; int x,y; while(cin >> s) { if(s=="End") break; cin >> x >> y; if(s=="Sub") updata(x, -y); else if(s=="Add") updata(x, y); else { int sum = getsum(y) - getsum(x-1); cout << sum << endl; } } } } 线段树做法: #include <cstdio> #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <cmath> #include <queue> #include <map> using namespace std; const int maxn = 50005; int T,n; int a[maxn]; string s; struct sss { int val; }SegTree[maxn<<2]; void build(int l,int r,int rt) { if(l==r) { SegTree[rt].val = a[l]; return; } int mid = (l+r)/2; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); SegTree[rt].val = SegTree[rt<<1].val + SegTree[rt<<1|1].val; //回溯方法 } void update(int L,int C,int l,int r,int rt) { if(l==r) { SegTree[rt].val += C; //这里是rt的val+=C,不是l或r的 return; } int mid = (l+r) >> 1 ; if(L <= mid) update(L, C, l, mid, rt<<1); else update(L, C, mid+1, r, rt<<1|1); SegTree[rt].val = SegTree[rt<<1].val + SegTree[rt<<1|1].val; } int query(int L,int R,int l,int r,int rt) { if(l>=L && r<=R) return SegTree[rt].val; if(l>R || r<L) return 0; int mid = (l+r)>>1; return query(L, R, l, mid, rt<<1) + query(L, R, mid+1, r, rt<<1|1); } int main() { scanf("%d",&T); for (int I=1;I<=T;I++) { cout << "Case " << I << ":" << endl; scanf("%d",&n); for (int i=1;i<=n;i++){ scanf("%d",&a[i]); } build(1, n, 1); //相当于初始化,不用像树状数组单独初始化了 while(cin >> s) { int x,y; if(s=="End") break; else { scanf("%d %d",&x,&y); if(s=="Add") update(x, y, 1, n, 1); if(s=="Sub") update(x, -y, 1, n, 1); if(s=="Query") cout << query(x, y, 1, n, 1) << endl; } } } return 0; }