一、一维树状数组
1.普通树状数组
#include <stdio.h>
#include <iostream>
using namespace std;
#define MAXN 500001
int n,m,flag;
int num[MAXN];
int Lowbit(int x) {return x & -x;}
void add(int x, int w){
for(;x<=n;x+=Lowbit(x)) num[x] += w;
}
int query(int x){
int ans=0;
for(;x>0;x-=Lowbit(x)) ans += num[x];
return ans;
}
int main(void){
int x=0,y=0;
cin >> n >> m;
for(int i=1;i<=n;i++){
cin >> x;
add(i,x);
}
for(int i=1;i<=m;i++){
cin >> flag >> x >> y;
if(flag == 1) add(x,y);
if(flag == 2) cout << query(y)-query(x-1) << endl;
}
return 0;
}
2.树状数组 + 差分
#include <stdio.h>
#include <iostream>
using namespace std;
#define MAXN 500001
int n,m,flag;
int num[MAXN];
int Lowbit(int x) {return x & -x;}
void add(int x, int w){
for(;x<=n;x+=Lowbit(x)) num[x] += w;
}
int query(int x){
int ans=0;
for(;x>0;x-=Lowbit(x)) ans += num[x];
return ans;
}
int main(void){
int x=0,y=0,k=0;
cin >> n >> m;
for(int i=1;i<=n;i++){
cin >> x;
add(i,x-y);
y = x;
}
for(int i=1;i<=m;i++){
cin >> flag;
if(flag == 1){
cin >> x >> y >> k;
add(x,k); add(y+1,-k);
}
if(flag == 2){
cin >> x;
cout << query(x) << endl;
}
}
return 0;
}
3.树状数组 + 离散化
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 300000
long long n,sol;
int num[MAXN],num2[MAXN],ti[MAXN],ri[MAXN],le[MAXN];
long long b[MAXN],a[MAXN];
long long Lowbit(int x) {return x & -x;}
void add(int x, int w){
for(;x<=n;x+=Lowbit(x)) num[x] += w;
}
long long query(int x){
long long ans=0;
for(;x>0;x-=Lowbit(x)) ans += num[x];
return ans;
}
int main(void)
{
cin >> n;
for(int i=1;i<=n;i++){
cin >> a[i];
b[i] = a[i];
}
/**************离散化**************/
sort(b+1,b+n+1);
int len = unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++)
a[i] = lower_bound(b+1,b+1+len,a[i])-b;
/**********************************/
for(int i=1;i<=n;i++){
le[i] += query(a[i]-1);
add(a[i],1);
}
memset(num,0,MAXN);
for(int i=n;i>=1;i--){
ri[i] += query(n)-query(a[i]);
add(a[i],1);
}
for(int i=1;i<=n;i++){
sol += ri[i]*le[i];
}
cout << sol << endl;
return 0;
}
二、二维树状数组
void add_2D(int x, int y, int w){
for(;x<=n;x+=Lowbit(x))
for(int j=y;j<=m;j+=Lowbit(j))
num[x][j] += w;
}
int query_2D(int x, int y){
int ans = 0;
for(;x>0;x-=Lowbit(x))
for(int j=y;j>0;j-=Lowbit(j))
ans += num[x][j];
return ans;
}
求子矩阵和:
设子矩阵四角坐标:
(x3,y3)(x4,y4)
(x2,y2)(x1,y1)
int ans = query_2D(x1,y1)-query_2D(x2,y2)-query_2D(x4,y4)+query_2D(x3,y3);