A - 敌兵布阵
http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=221#problem/A
#include <stdio.h> #include <string.h> struct seg { int l; int r; int sum; }q[2000001]; int num[50001]; int ans; void build(int rt,int ll,int rr) { if(ll == rr) { q[rt].l = q[rt].r = ll; q[rt].sum = num[ll]; return ; } int mid; q[rt].l = ll; q[rt].r = rr; mid = (ll + rr)/2; build(2*rt,ll,mid); build(2*rt + 1,mid + 1,rr); q[rt].sum = q[2 *rt].sum + q[2*rt+1].sum; } void update(int rt,int pos,int v) { if(q[rt].l == pos && q[rt].r == pos) { q[rt].sum+=v; return ; } int mid; mid = (q[rt].l + q[rt].r)/2; if(pos<=mid) update(2 *rt,pos,v); else update(2 * rt+1,pos,v); q[rt].sum = q[2 *rt].sum + q[2 *rt+1].sum; } void query(int rt,int s,int e) { int mid; mid = (q[rt].l + q[rt].r)/2; if(q[rt].l == s && q[rt].r == e) { ans+=q[rt].sum; } else if(e<=mid) { query(2 *rt,s,e); } else if(s>mid) { query(2 *rt+1,s,e); } else { query(2 *rt,s,mid); query(2 * rt+1,mid+1,e); } } int main() { int n,i; int t; int x,y; scanf("%d",&t); char str[11]; int k = 1; while(t--) { scanf("%d",&n); for(i = 1;i<=n;i++) { scanf("%d",&num[i]); } build(1,1,n); printf("Case %d:\n",k++); while(scanf("%s",str)) { if(str[0] == 'E') break; else if(str[0] == 'A') { scanf("%d%d",&x,&y); update(1,x,y); } else if(str[0] == 'S') { scanf("%d%d",&x,&y); update(1,x,-y); } else if(str[0] == 'Q') { scanf("%d%d",&x,&y); query(1,x,y); printf("%d\n",ans); ans = 0; } } } return 0; }
上边的是自己学的,注意的地方:
1. build 函数,要先判断,后赋值,然后遍历,不要忘记最后更新。
2.update 函数,先判断所给的根节点的值是否和要求的位置的点相同,相同的话就更新,不要忘记返回 NULL,如果不相同就 找到所给的根节点区间的中间值,用pos和mid进行判断,判断进入那里进行更新,节点的变化一定不要忘记。最后更新所有的节点。
3. query函数,先求所给根节点的区间值,判断索要查询的函数和根节点的区间是否相同,如果相同就加上该值,如果不相同就进行分类查找,e<=mid; mid>s,else
当为else时,query(2 *rt,s,mid);
query(2 *rt+1.mid+1,e);
#include<stdio.h> #include<string.h> struct Node { int sum; int l,r; }node[200001]; int num[50001]; int ans; void build(int rt,int ll,int rr) { if(ll==rr) { node[rt].l=node[rt].r=ll; node[rt].sum=num[ll]; return; } node[rt].l=ll; node[rt].r=rr; int mid=(ll+rr)/2; build(rt*2,ll,mid); build(rt*2+1,mid+1,rr); node[rt].sum=node[rt*2].sum+node[rt*2+1].sum; } void update(int rt,int pos,int v) { if(node[rt].l==pos&&node[rt].r==pos) { node[rt].sum+=v; return; } int mid; mid=(node[rt].l+node[rt].r)/2; if(pos<=mid) { update(rt*2,pos,v); } else update(rt*2+1,pos,v); node[rt].sum=node[rt*2].sum+node[rt*2+1].sum; } void query(int rt,int s,int e) { int mid; mid=(node[rt].l+node[rt].r)/2; if(node[rt].l==s&&node[rt].r==e) { ans+=node[rt].sum; } else if(s>mid) query(rt*2+1,s,e); else if(e<=mid) query(rt*2,s,e); else { query(rt*2,s,mid); query(rt*2+1,mid+1,e); } } int main() { int t,k=0; int n,i,x,y; char str[10]; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=1; i<=n; i++) scanf("%d",&num[i]); build(1,1,n); printf("Case %d:\n",++k); while(scanf("%s",str),str[0]!='E') { scanf("%d%d",&x,&y); if(str[0]=='Q') { ans=0; query(1,x,y); printf("%d\n",ans); } else if(str[0]=='A') { update(1,x,y); } else if(str[0]=='S') update(1,x,-y); } } return 0; }