模板 一维树状数组
单点修改,区间求和
#define lowbit(x) x&(-x)
const int maxn=100010;
int n,bit[2*maxn];
int query(int x){
int s=0;
while(x>0){
s+=bit[x];
x-=lowbit(x);
}
return s;
}
void change(int x,int v){
while(x<=n){
bit[x]+=v;
x+=lowbit(x);
}
}
区间修改,单点查询
将原数组存储成差分数组,根据差分的性质,在区间[l,r]上同时加上x可以处理成:
\(change(l,x)\)
\(change(r+1,-x)\)
查询下标为i的元素值可以处理成:
\(query(i)\)
区间修改,区间求和
设置两个BIT,bit和bit2
在区间[l,r]上同时加上x可以处理成:
\(change(bit,l,x)\)
\(change(bit,r+1,-x)\)
\(change(bit2,l,k*l)\)
\(change(bit2,r+1,-k*(r+1))\)
区间[l,r]的求和可以处理成:
\(query(bit,r)*(r+1)-query(bit2,r)-(query(bit,l-1)*l-query(bit2,l-1))\)
const int maxn=100010;
LL bit[maxn],bit2[maxn];
void add(LL *t,int x,LL v){
for(int i=x;i<=n;i+=lowbit(i)) t[i]+=v;
}
LL sum(LL *t,int x){
LL ans=0;
for(int i=x;i>0;i-=lowbit(i)) ans+=t[i];
return ans;
}
void update(int l,int r,LL k){
add(bit,l,k);
add(bit,r+1,-k);
add(bit2,l,k*l);
add(bit2,r+1,-k*(r+1));
}
LL getsum(int x){
return sum(bit,x)*(x+1)-sum(bit2,x);
}
LL query(int l,int r){
return getsum(r)-getsum(l-1);
}