1,作用:对数组某一区间的和的快速修改和维护
实现
树状数组把前缀和需要维护从1到i的点进行优化
通过lowbit函数进行快速的前缀和遍历
int lowbit(int x){
return x&(-x);//i取反+1与i
}
具体树状数组的实现:
给i加上一个数
for(int j=a1;j<=n;j+=lowbit(j)){
b[j]+=b1;
}
求前缀和:
for(int i=a1-1;i>0;i-=lowbit(i)){
sum1+=b[i];
}
最后附上树状数组的节点关系:
具体实现:
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int a[10000000];
int b[10000000];
int lowbit(int x){
return x&(-x);//i取反+1亦或i
}
int main(){
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
for(int j=i;j<=n;j+=lowbit(j)){
b[j]+=a[i];
}
}
while(m--){
int k;
scanf("%d",&k);
if(k==1){
int a1,b1;
scanf("%d %d",&a1,&b1);
for(int j=a1;j<=n;j+=lowbit(j)){
b[j]+=b1;
}
}
else{
int a1,b1,sum1=0,sum2=0;
scanf("%d %d",&a1,&b1);
for(int i=a1-1;i>0;i-=lowbit(i)){
sum1+=b[i];
}
for(int i=b1;i>0;i-=lowbit(i)){
sum2+=b[i];
}
printf("%d\n",sum2-sum1);
}
}
return 0;
}