树状数组做法:
#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;
}