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

Posted pecoz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VJ 敌兵布阵(单点修改 区间查询)相关的知识,希望对你有一定的参考价值。

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

① 单点查询

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;
}

以上是关于VJ 敌兵布阵(单点修改 区间查询)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1166 - 敌兵布阵 - [单点修改区间查询zkw线段树]

HDU - 1166 敌兵布阵 (线段树+单点修改,区间查询和)

算法系列学习线段树vs树状数组 单点修改,区间查询 [kuangbin带你飞]专题七 线段树 A - 敌兵布阵

HDU - 1166 - 敌兵布阵 线段树的单点修改,区间求和

敌兵布阵(线段树单点更新+区间查询)

A - 敌兵布阵(HDU 1166)