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 - 敌兵布阵