# binary indexed tree
* 計算前綴和,有前綴和也就可以算區間和
* **1-indexed**
> 如果要用 BIT 做最大值,數字只能被改大,做最小值,數字只能被改小
* 用差分$O(\log n)$區間操作
更新:
```cpp=
void update(int pos, int x){
while(pos<=n){
bit[pos]+=x;
pos+=pos & (-pos);
}
}
```
查詢:
```cpp=
int query(int pos){
int res=0;
while(pos>0){
res+=bit[pos];
pos-=pos & (-pos);
}
return res;
}
```
```cpp=
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
int a;
cin>>n;
rep(i,1,n+1){
cin>>a;
update(i, a);
}
cout << query(n) << NL;
}
```
區間加值
---
```cpp=
LL b1[500010]={0}, b2[500010]={0};//b1:prefix D, b2:prefix D*i
LL n, q, a, x, y, k;
void upd(LL *bit, LL pos, LL x){
while(pos<=n){
bit[pos]+=x;
pos+=pos & (-pos);
}
}
void range(LL l, LL r, LL x){
upd(b1, l, x);
upd(b1, r+1, -x);
upd(b2, l, l*x);
upd(b2, r+1, -(r+1)*x);
}
LL query(LL *bit, LL pos){
LL res=0;
while(pos>0){
res+=bit[pos];
pos-=pos & (-pos);
}
return res;
}
LL pre_sum(LL pos){
return (pos+1)*query(b1, pos)-query(b2, pos);
}
```
二維bit
---
https://tioj.ck.tp.edu.tw/problems/1869
```cpp=
#include <bits/stdc++.h>
#define EB emplace_back
#define vci vector<int>
#define PII pair<int,int>
#define F first
#define S second
#define rep(X, a,b) for(int X=a;X<b;++X)
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) (int)(a).size()
#define NL "\n"
#define LL long long
using namespace std;
LL bit[1050][1050]={0};
int n;
void update(int x, int y, LL v){
x++, y++;
while(x<=n){
int tmp=y;
while(tmp<=n){
bit[x][tmp]+=v;
tmp+=tmp & (-tmp);
}
x+=x & (-x);
}
}
LL get(int x, int y){
x++, y++;
LL res=0;
while(x>0){
int tmp=y;
while(tmp>0){
res+=bit[x][tmp];
tmp-=tmp & (-tmp);
}
x-=x & (-x);
}
return res;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>n;
while(cin>>t){
if(t==0) break;
if(t==1){
int a, b, z;
cin>>a>>b>>z;
update(a, b, z);
}
else{
int x1, y1, x2, y2;
cin>>x1>>y1>>x2>>y2;
cout<<get(x2, y2)-get(x1-1, y2)-get(x2, y1-1)+get(x1-1, y1-1)<<NL;
}
}
}
```