题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166
线段树实现代码如下:
//线段树区间求和
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 50005
int num[maxn];
struct segmentree
{
int l; //左端点
int r; //右端点
int sum; //区间总数
};
segmentree tree[4*maxn]; //总线段长度为N,开数组的话一般开到N的4倍
void build(int root,int l,int r) //root表示根节点,他的区间范围为[l,r]
{
tree[root].l=l;
tree[root].r=r;
if(tree[root].l==tree[root].r) //左右端点相等时就说叶子节点
{
tree[root].sum=num[l]; //赋初值
return ;
}
int mid=(l+r)/2;
build(root<<1,l,mid); //建立左孩子节点
build(root<<1|1,mid+1,r); //root<<1|1相当于root*2+1;建立右孩子节点
tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum; //更新父节点的sum值
}
void update(int root,int pos,int v) //root是根节点,pos和v表示:更新pos处的值为v
{
if(tree[root].l==tree[root].r) //叶子节点既是pos对应的位置
{
tree[root].sum=v;
return ;
}
int mid=(tree[root].l+tree[root].r)/2;
if(pos<=mid) //如果pos点是在root对应的左孩子的话,就在左孩子中找
update(root<<1,pos,v);
else update(root<<1|1,pos,v);
tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum; //更新父节点的sum值
}
int query(int root,int l,int r) //询问[l,r]区间
{
if(l<=tree[root].l&&r>=tree[root].r) //要查询的区间[l,r]包含root节点所表示的区间
return tree[root].sum;
int mid=(tree[root].l+tree[root].r)/2;
int cnt=0;
if(l<=mid) cnt+=query(root<<1,l,r);
if(r>mid) cnt+=query(root<<1|1,l,r);
return cnt;
}
int main()
{
int t,T=1;
scanf("%d",&t);
int n,a,b;
char str[10];
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]); //在i点初始的兵力数量
build(1,1,maxn); //构造线段树根节点为1,表示区间范围[1,maxn]
printf("Case %d:\n",T++);
while(scanf("%s",str),strcmp(str,"End"))
{
scanf("%d%d",&a,&b);
if(str[0]=='Q')
{
if(a>b) swap(a,b);
printf("%d\n",query(1,a,b));
}
else if(str[0]=='A')
{
num[a]+=b;
update(1,a,num[a]);
}
else if(str[0]=='S')
{
num[a]-=b;
update(1,a,num[a]);
}
}
}
return 0;
}
树状数组实现代码如下:
#include <cstdio>
#include <cstring>
using namespace std;
const int M=100010;
int a[M],n;
int lowbit(int i)
{
return i&(-i);
}
void update(int i,int x)
{
while(i<=n)
{
a[i]+=x;
i+=lowbit(i);
}
}
int query(int n)
{
int sum=0;
while(n>0)
{
sum+=a[n];
n-=lowbit(n);
}
return sum;
}
int main()
{
int t,T=1,x,y;
scanf("%d",&t);
while(t--)
{
memset(a,0,sizeof(a));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
update(i,x);
}
printf("Case %d:\n",T++);
char op[10];
while(scanf("%s",op))
{
if(op[0]=='E') break;
scanf("%d%d",&x,&y);
if(op[0]=='Q')
printf("%d\n",query(y)-query(x-1));
else if(op[0]=='A') update(x,y);
else update(x,-y);
}
}
return 0;
}