什麼是二維樹狀陣列
二維樹狀陣列
單點修改,區間查詢
#include const int maxn=4096+5;
typedef long long ll;
ll c[maxn][maxn];
int n,m;
int lowbit(int x)
void modify(int x,int y,int z)
ll getsum(int x,int y)
void solve()
else
}}int main()
區間修改單點查詢
當我們想要將乙個矩陣加上 \(x\) 時,怎麼做呢?如下面是給最中間的\(3\times 3\) 矩陣加上 \(x\) 時,差分陣列的變化:
# 更新時分別對矩陣四個角做如下更新(左上角為原點)
# 左上角座標(x1,y1),右下角座標(x2,y2)
# 更新時在(x1,y1)處 +x,相當於對矩陣 (x1,y1)到(n,m)都加上了x
# 在(x1,y2+1)處-x,消除對矩陣(x1,y2+1)到(n,m)多加的x
# 在(x2+1,y1)處-x,消除對矩陣(x2+1,y1)到(n,m)多加的x
# 在(x2+1,y2+1)處+x,(x2+1,y2+1)到(n,m)被上面三個操作都就算了一遍,被加了一次x,減去兩次x,所以再加一次x消除影響。
0 0 0 0 0
0 +x 0 0 -x
0 0 0 0 0
0 0 0 0 0
0 -x 0 0 +x
# 單點getsum求值時,矩陣結果如下:
0 0 0 0 0
0 x x x 0
0 x x x 0
0 x x x 0
0 0 0 0 0
\(code\)
#include const int maxn=4096+5;
typedef long long ll;
ll c[maxn][maxn];
int n,m;
int lowbit(int x)
void modify(int x,int y,int z)
}ll getsum(int x,int y)
void solve()
else
}}int main()
區間修改、區間查詢
把上式展開可以得到:
\[\begin
sum[x][y]&=(x+1-i)*(y+1-j)*\sum_^x\sum_^y d[i][j]\\
&=((x+1)*(y+1)-(x+1)*j-(y+1)*i+i*j)*\sum_^x\sum_^y d[i][j]\\
&=(x+1)*(y+1)*\sum_^x\sum_^y d[i][j]-(y+1)*\sum_^x\sum_^y d[i][j]*i-(x+1)*\sum_^x\sum_^y d[i][j]*j+\sum_^x\sum_^y d[i][j]*i*j\\
\end
\]所以我們只需開四個樹狀陣列,分別維護:\(d[i][j],d[i][j]*i,d[i][j]*j,d[i][j]*i*j\) 。
\(code\)
#include const int maxn=2048+5;
typedef long long ll;
ll c1[maxn][maxn],c2[maxn][maxn],c3[maxn][maxn],c4[maxn][maxn];
int n,m;
int lowbit(int x)
void modify(ll x,ll y,ll z)
}ll getsum(ll x,ll y)
void solve()
else
}}int main()
樹狀陣列 二維
首先初始陣列還是a陣列,二維的 搞乙個b陣列,也是二維,b i 就是a陣列第i行的一維樹狀陣列 b 2 1 a 2 1 b 2 2 a 2 1 a 2 2 b 2 3 a 2 3 最後我們來搞乙個c陣列,當然它還是二維的hhh c 1 就是第一行的樹狀陣列,c 2 是第一行加第二行,c 3 是第三行...
樹狀陣列 二維樹狀陣列模板
樹狀陣列模板 int lowbit int x int add int x,int val int que int x 模板題 題解 include include include using namespace std int c 300000 rank 300000 int n int lowb...
樹狀陣列及二維樹狀陣列
一直以為樹狀陣列能用線段樹水過去,直到我今天碰上了樹狀陣列模板題。然後就是開始認真的學習樹狀陣列,突然發現怎麼這麼好寫qwqqqq。部分 一.樹狀陣列 樹狀陣列是一種資料結構,核心思想是利用二進位制的補碼思想。首先就是樹狀陣列的結構圖 然後我們對他進行變形 是不是感覺更好理解了呢?然後我們對其進行標...