HDU 1166 敌兵布阵(单点修改 区间查询)

原题
这是一道基于树状数组基本操作的板子题。
本题涉及到树状数组几个基本操作:

① 单点查询

int query(int x)
{
    int ans=0;
   for(;x;x-=(x&-x))
   {
      ans+=c[x];
   }
   return ans;
}

② 单点修改

void add(int i,int j)
{
   for(;i<=n;i+=(i&-i))
   {
      c[i]+=j;
   }
}

③ 区间查询
我们知道树状数组储存的是前缀和,所以要查询区间[l,r]中所有数的和,只需计算ask(r)-ask(l-1)。

所以该题只需简单的模拟即可,WA了一发的原因是因为忘记了树状数组要先初始化为0;
AC代码:

#include<bits/stdc++.h>
using namespace std;
int a[50005],c[50005],n;
int query(int x)//单点查询
{
    int ans=0;
   for(;x;x-=(x&-x))
   {
      ans+=c[x];
   }
   return ans;
}
void add(int i,int j)//单点修改
{
   for(;i<=n;i+=(i&-i))
   {
      c[i]+=j;
   }
}
int main()
{
    int T,cnt=1;
    cin>>T;
    while(T--)
    {
       scanf("%d",&n);
       for(int i=1;i<=n;i++)
       {
         scanf("%d",&a[i]);
         add(i,a[i]);
       }
       char b[10];
       int i,j;
       printf("Case %d:
",cnt++);
       while(~scanf("%s",b))
       {
           if(b[0]=='E')
            break;
          scanf("%d%d",&i,&j);
          if(b[0]=='Q')
          {
             int x=query(i-1),y=query(j);
             printf("%d
",y-x);
          }
          else if(b[0]=='A')
          {
             add(i,j);
          }
          else if(b[0]=='S')
            add(i,-j);
       }
       memset(c,0,sizeof(c));//要注意树状数组的初始化
    }
return 0;
}

戒骄戒躁,百炼成钢!
原文地址:https://www.cnblogs.com/Pecoz/p/12396776.html