原题P3374
$lowbit()$将某数在二进制下的高位$1$去掉,只剩最后一个最低位$1$。
例如 $lowbit(3_{10}(101_{2}))=1_{10}(001_{2})$
那么,若有一个数组$a[n]$,它的前缀和的树状数组为$t$
那么
1 2 3 4 5 6 7
| while(j<=n){
t[j]+=a[i];
j+=lowbit(j);
}
|
(初始化)
若我们需要$a[i]+a[i+1]+···+a[j]$,
则需要
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| i--;
while(x){
x_sum+=t[x];
x-=lowbit(x);
}
while(y){
y_sum+=t[y];
y-=lowbit(y);
}
return y_sum-x_sum;
|
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| #include<bits/stdc++.h>
int n,m,t[500002];
int lowbit(int k){
return k&-k;
}
void add(int x,int y){
while(x<=n){
t[x]+=y;
x+=lowbit(x);
}
return;
}
int sum(int x,int y){
int x_sum=0,y_sum=0;
x--;
while(x){
x_sum+=t[x];
x-=lowbit(x);
}
while(y){
y_sum+=t[y];
y-=lowbit(y);
}
return y_sum-x_sum;
}
int main(){
scanf("%d%d",&n,&m);
for(int i(1);i<=n;i++){
int in;
scanf("%d",&in);
add(i,in);
}
for(int i(1);i<=m;i++){
int c,a,b;
scanf("%d%d%d",&c,&a,&b);
if(c==1){
add(a,b);
}else{
printf("%d\n",sum(a,b));
}
}
return 0;
}
|