原题链接:传送门
刚学了树状数组(感谢PK学长讲解),还是补一篇博客吧。树状数在单点更新、查询操作时要比线段树快得多,而且更省空间。
树状数组学习博客:https://www.cnblogs.com/hsd-/p/6139376.html
http://www.cppblog.com/menjitianya/archive/2015/11/02/212171.html
树状数组版:
#include <iostream>
#include <cstring>
#include <cstdio>
#define lowbit(x) x&-x
using namespace std;
const int N = 50005;
int tree[N];
int t,n;
void add(int k,int num) {
while(k <= n) {
tree[k] += num;
k += lowbit(k); //求父节点
}
}
int getSum(int k) {
int ans = 0;
while(k) {
ans += tree[k];
k -= lowbit(k); //求前一个父节点
}
return ans;
}
int main() {
int Case = 1,x;
scanf("%d",&t);
while(t--) {
memset(tree,0,sizeof(tree));
printf("Case %d:\n",Case++);
scanf("%d",&n);
for(int i=1; i<=n; i++) { //必须要从1开始
scanf("%d",&x);
add(i,x);
}
char order[6];
while(~scanf("%s",order)) {
if(order[0] == 'E') {
break;
}
int a,b;
scanf("%d%d",&a,&b);
if(order[0] == 'A') {
add(a,b);
} else if(order[0] == 'S') {
add(a,-b);
} else printf("%d\n",getSum(b)-getSum(a-1));
}
}
return 0;
}
线段树版:
#include <iostream>
#include <cstring>
#include <cstdio>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int N = 50005;
int num[N<<2];
int n;
void PushUp(int rt) {
num[rt] = num[rt<<1] + num[rt<<1|1];
}
void Build(int l,int r,int rt) {
if(l == r) {
num[rt] = 0;
scanf("%d",&num[rt]);
return ;
}
int m = (r-l)/2 + l;
Build(lson);
Build(rson);
PushUp(rt);
}
void Updata(int x,int d,int l,int r,int rt) {
if(l == r) {
num[rt] += d;
return ;
}
int m = (r-l)/2 + l;
if(m >= x) Updata(x,d,lson);
else Updata(x,d,rson);
PushUp(rt);
}
int Query(int L,int R,int l,int r,int rt) {
if(L <= l && r <= R) {
return num[rt];
}
int m = (r-l)/2 + l;
int ans = 0;
if(m >= L) ans += Query(L,R,lson);
if(m < R) ans += Query(L,R,rson);
return ans;
}
int main() {
int t,Case = 1;
scanf("%d",&t);
while(t--) {
printf("Case %d:\n",Case++);
scanf("%d",&n);
Build(1,n,1);
char order[6];
int x,d;
while(~scanf("%s",order)) {
if(order[0] == 'E') {
break;
}
scanf("%d%d",&x,&d);
if(order[0] == 'A') {
Updata(x,d,1,n,1);
} else if(order[0] == 'S') {
Updata(x,-d,1,n,1);
} else printf("%d\n",Query(x,d,1,n,1));
}
}
return 0;
}