- admin's blog
【单点修改+区间查询】树状数组
- @ 2024-1-6 19:16:20
【单点修改+区间查询】树状数组
树状数组和线段树的区别就是,树状数组好写,没啦 同样的树状数组能实现区间的快速操作,但是根据题目的要求不同树状数组还真不同。
lowbit(int x)
在树状数组中最深奥的一个用法,他能获取二进制x的最后一位
lowbit(x)= x & (-x)
懒得证明,但是肯定是正确的
add(int x,int v)
这段代码的意思是将x位置上的值+v
利用二进制的关系,我们因为需要获取区间的内容,所以我们将x到n的二进制倍数都加上v。
很抽象,但能用就行
void add(int x,int v)
{
while(x<=n)
{
a[x]+=v;
x+=lowbit(x);
}
}
getsum(int x)
获取前x的和,利用二进制关系,反着向前将值加上,就是得到的结果
int getsum(int x)
{
int ans=0;
while(x)
{
ans+=a[x];
x-=lowbit(x);
}
return ans;
}
Code
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&-x
const int N=5e5+12;
int a[N],n,m;
void add(int x,int v)
{
while(x<=n)
{
a[x]+=v;
x+=lowbit(x);
}
}
int getsum(int x)
{
int ans=0;
while(x)
{
ans+=a[x];
x-=lowbit(x);
}
return ans;
}
int main(){
cin>>n>>m;
int p,x,y;
for(int i=1;i<=n;i++)
{
cin>>x;
add(i,x);
}
while(m--)
{
cin>>p>>x>>y;
if( p==1 )
{
add(x,y);
}
else{
cout<<getsum(y)-getsum(x-1)<<endl;
}
}
}