简介
树状数组就是一种能在O(log n)内查询或修改的数据结构,
它的代码极其简洁,是水题党的好帮手 适合解决单点修改与区间查询。
其大概的结构是这样的:
其中
A
A
A数组就是我们的树状数组,
A
i
=
1
A_i=1
Ai=1~
i
i
i之和,即前缀和。val代表数据的权值。
思路
每次将一个点进行修改时,就将它所对应的树状数组以及它的父节点更新:
void update(int x,int y)
{
for(; x<=n; x+=x&-x) A[x]+=y;
}
每次查询时,通过前缀和解决就行了:
int que(int x)
{
int ans=0;
for(; x; x-=x&-x) ans+=c[x];
return ans;
}
ans=que(y)-que(x-1);
代码
#include<iostream>
using namespace std;
#define int long long
int n,m,v,c[1000001];
void update(int x,int y)
{
for(; x<=n; x+=x&-x) c[x]+=y;
}
int que(int x)
{
int ans=0;
for(; x; x-=x&-x) ans+=c[x];
return ans;
}
signed main()
{
scanf("%lld%lld",&n,&m);
for(int i=1; i<=n; ++i)
{
scanf("%lld",&v);
update(i,v);
}
for(int i=1; i<=m; ++i)
{
int o;
scanf("%lld",&o);
if(o==1)//o=1表示修改
{
int x,k;//给 i 位加 k
scanf("%lld%lld",&x,&k);
update(x,k);
}
else
{
if(o==2)//o=2表示查询
{
int x,y;
scanf("%lld%lld",&x,&y);
int ans=que(y)-que(x-1);
printf("%lld\n",ans);
}
}
}
}