HDU 1166 敌兵布阵

HDU 1166 敌兵布阵

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1166
/**/ /*
题意:
    给定N(N <= 50000)个数, 表示敌人有N个工兵营地,接下来有N个正整数, 第
i个正整数ai代表第i个工兵营地里开始时有ai个人(1<=ai<=50)。
接下来每行有一条命令,命令有4种形式:
(1)Add i j   ,i和j为正整数, 表示第i个营地增加j个人(j不超过30)
(2)Sub i j   ,i和j为正整数, 表示第i个营地减少j个人(j不超过30);
(3)Query i j ,i和j为正整数, i<=j,表示询问第i到第j个营地的总人数;
(4)End 表示结束,这条命令在每组数据最后出现

解法:
    树状数组 或者 线段树

思路:
    典型的树状数组模板题,Add和Sub是同一个操作,Sub就是Add一个负的值,只
是Sub之前先要判断这个点有没有这么多,询问就是利用树状数组的成段求和。
*/


#include 
< iostream >

using   namespace  std;

#define  maxn 1000010

int  c[maxn], n;
int  a[maxn];
char  ch[ 100 ];

int  lowbit( int  x)  {
    
return x & (-x);
}


void  Add( int  x,  int  add)  {
    
while(x <= n) {
        c[x] 
+= add;    
        x 
+= lowbit(x);
    }

}


int  sum( int  x)  {
    
int s = 0;
    
while(x > 0{
        s 
+= c[x];
        x 
-= lowbit(x);
    }

    
return s;
}


int  main()  {
    
int t, as, bs, i, q = 1;
    scanf(
"%d"&t);
    
while(t--{
        scanf(
"%d"&n);
        memset(c, 
0sizeof(c));
        
for(i = 1; i <= n ;i++{
            scanf(
"%d"&a[i]);
            Add(i, a[i]);
        }

        printf(
"Case %d:\n", q++);
        
while(scanf("%s" , ch) != EOF) {
            
if(!strcmp(ch, "End"))
                
break;
            
else if(!strcmp(ch, "Query")) {
                scanf(
"%d%d"&as&bs);
                printf(
"%d\n", sum(bs) - sum(as - 1));
            }
else if(!strcmp(ch, "Add")) {
                scanf(
"%d%d"&as&bs);
                Add(
as, bs);
            }
 else if(!strcmp(ch, "Sub")) {
                scanf(
"%d%d"&as&bs);
                Add(
as-bs);
            }

        }

        
    }

}

你可能感兴趣的:(HDU 1166 敌兵布阵)