题目链接: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; }