HDOJ 1166.敌兵布阵

2015-06-08

问题简述:

  原题的题意相当于有一些连续摆放的箱子,里面装着球,球的数量可以加减,现要查询几个连续的箱子里球的总数,其中存在放球和拿球的操作。

  原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166

解题思路:

  查询区间和的问题,可以使用线段树。

  最初的输入相当于构建线段树的过程;每一次的加减相当于对线段树进行更新;最后使用线段树的查询区间和算法直接得出答案。

源代码:

 1 /*
 2 OJ: HDOJ
 3 ID: forever
 4 TASK: 1166.敌兵布阵
 5 LANG: C++
 6 NOTE: 线段树
 7 */
 8 #include <cstdio>
 9 
10 const int MAX=200005;
11 int a[MAX];
12 char str[10];
13 
14 void build(int l,int r,int flag) {
15     if(l==r) {
16         scanf("%d",&a[flag]);
17         return;
18     }
19     int m=(l+r)/2;
20     build(l,m,flag*2);
21     build(m+1,r,flag*2+1);
22     a[flag]=a[flag*2]+a[flag*2+1];
23 }
24 
25 void update(int x,int y,int l,int r,int flag) {
26     if(l==r) {
27         a[flag]+=y;
28         return;
29     }
30     int m=(l+r)/2;
31     if(x<=m)
32         update(x,y,l,m,flag*2);
33     else
34         update(x,y,m+1,r,flag*2+1);
35     a[flag]=a[flag*2]+a[flag*2+1];
36 }
37 
38 int query(int x,int y,int l,int r,int flag) {
39     if(x<=l&&r<=y)
40         return a[flag];
41     int m=(l+r)/2;
42     int ans=0;
43     if(x<=m)
44         ans+=query(x,y,l,m,flag*2);
45     if(y>m)
46         ans+=query(x,y,m+1,r,flag*2+1);
47     return ans;
48 }
49 
50 int main()
51 {
52     int t,n,x,y,k=1;
53     scanf("%d",&t);
54     while(t--) {
55         scanf("%d",&n);
56         build(1,n,1);
57         printf("Case %d:\n",k++);
58         while(scanf("%s",str)&&str[0]!='E') {
59             scanf("%d %d",&x,&y);
60             if(str[0]=='Q')
61                 printf("%d\n",query(x,y,1,n,1));
62             else if(str[0]=='A')
63                 update(x,y,1,n,1);
64             else if(str[0]=='S')
65                 update(x,-y,1,n,1);
66         }
67     }
68     return 0;
69 }

 

posted @ 2015-06-08 13:03  ACMan  阅读(319)  评论(0编辑  收藏  举报