樹狀陣列(總結篇)

2022-03-28 07:24:33 字數 2103 閱讀 4102

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在最壞情況下...