by zyq / 2014 / 7
樹狀陣列何其牛逼只能這麼形容啊。
首先,網上好多對樹狀陣列基礎知識講解的在這就不細講了。可以參考
(內容比較老了)
下面總結一下樹狀陣列的題型 :
1.最簡單的單點更新區間查詢 。 其實這個是樹狀陣列的精髓了,不過入門的時候都會做些簡單題找感覺吧。
下面附上簡單題找感覺,動腦子的題後面貼。
(二維的裸題呢)
(又是乙個二維的裸題)
2.插線問點問題:
這是乙個經典問題,題目描述為:給連續區間內同時給出某種操作。 然後詢問單點的值是多少。
例如:把區間【a,b-1】內的數同時加上v,然後詢問c點的值。 我們可以這麼操作:在更新a處的值(加上v) ,然後更新b 處的值(減去v)
這樣任何落在區間【a,b-1】的點都會加上1不在區間上的點都不變。
可以參考上圖
(三維問題)
(維護多顆樹狀陣列問題)
(維護多顆樹狀陣列問題)
插線問點是離線樹狀陣列的基礎問題哦。。
3:區間修改區間查詢的問題 。
這個問題顯得不是那麼重要(用線段樹組搞很簡單的)。用樹狀陣列搞就是在深入理解下他的用法。
我們可以維護兩個樹狀陣列。
具體可以搞出
我的**:
/*by cao ni ma
hehe
*/#include
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
typedef long
long ll;
const
int max = 100000+10;
const
int inf = 0x3f3f3f3f;
ll c[2][max];
int n,m;
int lowbit(int x)
void add(ll *c,int x,ll val)
ll sum(ll *c,int x)
ll val[max]; char str[3];
int main()
for(int i=0;i"
%s",str);
if(str[0]=='
q')
else }}
return0;}
view code
4:離線處理問題;
這種型別的問題主要是考慮到 查詢之間存在某種影響,為了消除這些影響我們需要按某些順序來處理這些查詢。
最常見的就是按區間右端點(或左端點)排序從左向右掃瞄(從右向左)。具體的可以搞幾道題就明白了。
(經典題,求區間不出復數字的個數)
(多校賽很不錯的題目) (其實相當於是括號匹配,只不過這裡括號變成了因子)。
接下來是我在cf上千辛萬苦找的題。
(和上面的操作看似相反其實可以轉化。)
(很經典的題目)
5.最後乙個經典問題就是樹形結構程式設計線型
這類問題一般是修改某個節點的子孫節點然後問修改之後的狀態。 我們利用深搜吧記錄下第一次訪問v的位置和最後一次訪問v的位置 這樣
樹形結構就能搞成線性操作了。
詳見dfs片段。
intdfs(
intu,
intpre,
intd)
end[u]=dfs_clock;
}下面是幾道類似的題目:
能搞出上面的題目基本上算是入門了餓。
接下來可以搞搞其他的資料結構會有更深的認識。
下面列出幾道樹狀陣列的神題(我認為)
(這道題是二維操作維護四顆樹狀陣列,比賽時吧二維線段樹都卡掉了)
(我還沒搞出來,我太弱了。)
其餘的題目以後搞出來在加。 (勿轉)
後續新增的題目 (線段樹都能搞):
樹狀陣列總結篇
傳送門 題意 在日本的東海岸和西海岸修交通線,問這些交通線有多少交叉點 解法 按照x座標公升序,相同的情況下y公升序排序,然後查詢在之前有多少滿足條件的即可 include include include include define n 1005 define ll long long using...
樹狀陣列總結
樹狀陣列的基本知識已經被各種大牛和菜鳥講到爛了,我就不多說了,下面給出基本操作的 假定原陣列為a 1.n 樹狀陣列b 1.n 考慮靈活性的需要,使用int a傳陣列。define lowbit x x x int sum int a,int x void update int a,int x,int...
樹狀陣列總結
樹狀陣列是對乙個陣列改變某個元素和求和比較實用的資料結構。兩中操作都是o logn 在解題過程中,我們有時需要維護乙個陣列的字首和s i a 1 a 2 a i 但是不難發現,如果我們修改了任意乙個a i s i s i 1 s n 都會發生變化。可以說,每次修改a i 後,調整字首和s在最壞情況下...