今天接觸二維樹狀陣列。
其實,要明確的一點是,不管是一維還是二維樹狀陣列,都只是工具而已,只是幫助我們更快地求和,查詢,樹狀陣列的這些操作都可以用我們平常的方法求,例如一直加。
面對乙個二維陣列,我們要求它們的和,會怎麼做呢?
先求出第一行的總和
再求出第二行的總和
再求出第三行的總和
..........
求出最後一行的總和
最後就是每一行都加起來,得出來的就是二維陣列的總和。
那我們用樹狀陣列來幫我們 「算快一點」 呢?
第一行是乙個樹狀陣列,區間求和
第二行是乙個樹狀陣列,區間求和
第三行是乙個樹狀陣列,區間求和
..........
最後一行也是樹狀陣列,區間求和
假如有 100000 行呢?
那我們把每一行樹狀陣列當做乙個值,變成一列,對這一列求和,那不就變成乙個一維樹狀陣列了嗎
int sum( int x , int y )
x -= lower( x ) ;
} return ans ;
}
這是對 1- x , 1-y 所表示的矩陣的求和函式,就是巢狀的一維求和呢
換個方式看
ll sum( int *c , int x )
return ans ;
}int matrix_sum( int x , int y )
return ans ;
}
應該很清楚了吧
更新操作一樣的,也都是一維樹狀陣列的更新,然後每一行再看做一列,還是一維更新
void update( int x , int y , int add )
x += lower( x ) ;
}}
換個方式看
void update( int *c , int x , int add )
}void matrix_update( int x , int y , int add )
}
其實都是我們正常對矩陣的求和操作,先求出每一行,再求這些行的總和。樹狀陣列,線段樹只是讓我們求得更快而已。
也就可以推廣到三維,四維..... n 維,都是樹狀陣列的巢狀。
貼一道例題:poj 2155
對二維陣列的求和,求出來的和,如果是偶數,說明被修改回來了,如果是奇數,說明沒被改回來
#include #include #include using namespace std ;
#define ll long long
#define lower(x) x&-x
int n , q ;
int c[1002][1002] ;
void update( int x , int y , int add )
x += lower( x ) ; }}
int sum( int x , int y )
x -= lower( x ) ;
} return ans & 1 ;
}int main()
else
} if( cases ) printf( "\n" ) ;
} return 0 ;
}
一維樹狀陣列和二維樹狀陣列
hdu1166敵兵布陣 樹狀陣列適用於頻繁對陣列元素進行修改,同時又要查詢陣列內任一區間元素之和。聽說線段樹也可以做,線段樹的作用 點修改,區間查詢,區間修改。include include include include using namespace std int a 50005 int c ...
樹狀陣列 二維樹狀陣列模板
樹狀陣列模板 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。部分 一.樹狀陣列 樹狀陣列是一種資料結構,核心思想是利用二進位制的補碼思想。首先就是樹狀陣列的結構圖 然後我們對他進行變形 是不是感覺更好理解了呢?然後我們對其進行標...