| 
			
		 | 
		
			
				
					
	
		
		
		题目链接: 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, 0, sizeof(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);
              }
          }
          
      }
  } 
		 
		
	 
	 
	
	
	    
    
 
				
			 
		 |