# 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; } } } ```