我在前面已經介紹過了樹狀陣列的各種操作,但是你會輕易的發現前面我們介紹的樹狀陣列都是一維的,那既然一維可以,那麼會不會有二維的樹狀陣列呢?
答案是肯定的。
那麼我今天就來教大家如何實現二維的樹狀陣列。
今天我介紹基本的功能:
對二維陣列內某一點加上乙個值
求一原點為乙個端點的子矩陣和
求以二維陣列中的兩個點為端點的子矩陣和
我們先來講講怎麼去表示。(分析字太多了,以下的分析採用南宮逸辰的分析)
陣列a的樹狀陣列定義為:
c[x][y] = ∑ a[i][j], 其中,
x-lowbit(x) + 1 <= i <= x,
y-lowbit(y) + 1 <= j <= y.
例:舉個例子來看看c的組成。
設原始二維陣列為:
a=,
, ,
}; 那麼它對應的二維樹狀陣列c呢?
記: b[1]= 這是第一行的一維樹狀陣列
b[2]= 這是第二行的一維樹狀陣列
b[3]= 這是第三行的一維樹狀陣列
b[4]= 這是第四行的一維樹狀陣列
那麼:
c[1][1]=a11,c[1][2]=a11+a12,c[1][3]=a13,c[1][4]=a11+a12+a13+a14,c[1][5]=a15,c[1][6]=a15+a16,…
這是a第一行的一維樹狀陣列
c[2][1]=a11+a21,c[2][2]=a11+a12+a21+a22,c[2][3]=a13+a23,c[2][4]=a11+a12+a13+a14+a21+a22+a23+a24,
c[2][5]=a15+a25,c[2][6]=a15+a16+a25+a26,…
這是a陣列第一行與第二行相加後的樹狀陣列
c[3][1]=a31,c[3][2]=a31+a32,c[3][3]=a33,c[3][4]=a31+a32+a33+a34,c[3][5]=a35,c[3][6]=a35+a36,…
這是a第三行的一維樹狀陣列
c[4][1]=a11+a21+a31+a41,c[4][2]=a11+a12+a21+a22+a31+a32+a41+a42,c[4][3]=a13+a23+a33+a43,…
這是a陣列第一行+第二行+第三行+第四行後的樹狀陣列
好,南宮逸辰分析結束。
我簡單總結一下,說白了,就是每一行都是乙個樹狀陣列,
以行為元素,整個列也是乙個樹狀陣列。(這句話請記住,這個思想會貫穿始終)
既然如此,我相信**也很快就出來了,接下來我就來給出**,並進行簡單的解釋。
void add(int x,int y,int p)
x+=lowbit(x);
} }
這個根據我剛剛說的兩個樹狀陣列(那句貫穿始終的話),就很容易理解了。
我們外圍迴圈列舉每一行,內迴圈在行內進行一維樹狀陣列的單點修改,從而實現二維樹狀陣列的單點修改。
int
sum(int x,int y)
x-=lowbit(x);
} return result;
}
還是那句貫穿始終的話,外圍枚舉行,內圍則是一維樹狀陣列前幾項和。這樣就能完成我們的任務了。
int ask(int x1,int y1,int x2,int y2)
和以為樹狀陣列一樣,我們依然借助sum去求。
但是,我們看到,這個公式似乎很長,別急,別暈,聽我解釋一邊即可明白。
首先宣告,我們保證x2>=x1,y2>=y1
下面讓我們先來看乙個圖:
紅色的矩形是我們要求的。
我們這裡為了和計算機裡二維陣列的保持一致,我們把x座標視為縱座標。(感謝qie_wei指正我的錯誤)
首先sum(x2,y2)很顯然是整個大矩形,
sum(x1-1,y2)和sum(x2,y1-1)則是綠色和黃色的兩個矩陣(不含紅色邊),很明顯這是我們不要的,所以我們用大的矩陣減去這兩個小矩陣。
但是,減完以後我們會發現藍色陰影部分的矩陣被減了兩次,很明顯減多了,所以我們還需要加上sum(x1-1,y1-1)
這樣就成了我給的公式。
不是很難,但改進的很巧妙。
注意複習,隨後我會發一道練習題。
樹狀陣列 二維樹狀陣列模板
樹狀陣列模板 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。部分 一.樹狀陣列 樹狀陣列是一種資料結構,核心思想是利用二進位制的補碼思想。首先就是樹狀陣列的結構圖 然後我們對他進行變形 是不是感覺更好理解了呢?然後我們對其進行標...
樹狀陣列及二維樹狀陣列
樹狀陣列或者二叉索引樹也稱作binary indexed tree,又叫做fenwick樹 它的查詢和修改的時間複雜度都是log n 空間複雜度則為o n 這是因為樹狀陣列通過將線性結構轉化成樹狀結構,從而進行跳躍式掃瞄。通常使用在高效的計算數列的字首和,區間和。為什麼要用樹狀陣列 線段樹比樹狀陣列...