敌兵布阵

hdu1166:http://acm.hdu.edu.cn/showproblem.php?pid=1166

题意:n个阵营一字排开,每个初始有a[i]个人。现有两种操作:Q a b 查询[a,b]之间总人数并输出A/S a b 在a号位添加/删除b个人
题解:用线段树维护,就是单点更新,区间查询。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdio>
 5 using namespace std;
 6 int n,a,b;
 7 struct Node{
 8     int left;//左二子 
 9     int right;//右儿子 
10     int sum;//一顶点为子树的和 
11 }node1[50005*4];//这里一定要注意,是4倍的点,不然会越界,自己犯过错 
12 void build(int l,int r,int idx){//建树 
13      node1[idx].left=l;
14      node1[idx].right=r;//注意这里,第一次,把这里弄丢了 
15     if(l==r){
16       scanf("%d",&node1[idx].sum);//到底就读取数据 
17         return;
18     }
19     int midx=(l+r)>>1;
20     build(l,midx,idx<<1);//向下建立子树 
21     build(midx+1,r,(idx<<1)+1);
22     node1[idx].sum=node1[idx<<1].sum+node1[(idx<<1)+1].sum;//建完子树,向上更新父亲节点的和 
23 }
24 int query(int s,int t,int idx){//区间查询 
25     if(s==node1[idx].left && t==node1[idx].right){
26         return node1[idx].sum;
27     }
28     int midx=(node1[idx].left+node1[idx].right)/2;//这里第一次忘记了/2,找了几个小时 
29     if(midx>=t) return query(s,t,idx*2);//在左二子 
30     else if(midx<s)return query(s,t,idx*2+1);//在右儿子 
31     else {
32         return (query(s,midx,idx*2)+query(midx+1,t,idx*2+1));//在中间 
33     }
34 } 
35 void update(int p,int add,int l,int r,int idx ){//单点更新 
36     if(node1[idx].left==node1[idx].right){
37     node1[idx].sum+=add;
38       return;
39       }
40      int midx=(r+l)/2;
41      if(p<=midx)
42        update(p,add,l,midx,idx*2);
43      else 
44       update(p,add,midx+1,r,idx*2+1);
45      node1[idx].sum=node1[idx*2].sum+node1[idx*2+1].sum; //向上更新,不是+=,是=  
46 }
47 int main(){
48     int cas;char ss[8];
49     scanf("%d",&cas);
50     int t=1;
51     while(cas--){
52         printf("Case %d:\n",t++);
53         scanf("%d",&n);
54         build(1,n,1);
55     while(~scanf("%s",ss)){
56           if(ss[0]=='E')break;
57           if(ss[0]=='Q'){
58               scanf("%d%d",&a,&b);
59               printf("%d\n",query(a,b,1));
60           }
61          else if(ss[0]=='A'){
62            scanf("%d%d",&a,&b);
63            update(a,b,1,n,1);    
64           } 
65          else{
66              scanf("%d%d",&a,&b);
67            update(a,-b,1,n,1);    
68          }
69       }    
70     }
71 }
View Code

 

posted on 2013-10-25 15:11  天依蓝  阅读(157)  评论(0编辑  收藏  举报

导航