hdu 1754 I Hate It 樹狀陣列

2021-06-21 14:45:54 字數 1533 閱讀 3354

小記:對於求區間的最值問題,如何利用樹狀陣列來解決它:

idx[i]表示1-i區間中最大的值,a是存放元素陣列

利用樹狀陣列來求解區間最值問題的原理就是樹狀陣列對二進位制的利用,對於樹狀陣列的第k個陣列元素值它的意義代表著區間[k - lowbit(k) +1, k ]的最大值,在它的下面有lowbit(k)個類似的區間,我們統計出其中的每乙個區間的最值,然後求出最大的就是它自己的值了。

void init()

}}

這裡是初始化idx陣列元素的值,但是在執行init之前我們必須對idx初始化乙個不影響結果的小值。我們可以改用另一種:

void init()

}}

這樣就可以直接執行init函式了,原理就是前面說的,通過它自己包含的子區間來更新自己的idx的值。

然後我們要查詢某個區間的最值,例如[l,r],那麼我們就從右邊開始算起,只要它所包含的區間在[l,r]之間,那麼我就取出它的區間最值,對於某個r,只要其區間[r-lowbit(r)+1,r]是在[l,r]之間的,那麼我們就將其idx[r]值來更新結果。如果不在,或者區間超過了r-l+1,那麼我們就令r在減去個1,這樣我們可以看r的下乙個區間,只要一直走就可以更新完所有在[l,r]之間的所有區間,然後我們的結果就出來了。

int query(int l,int r)

} return ans;

}

然後為了能夠實現邊查邊改我們,通過初始化的那樣的方法,對某點更新了a值之後,那麼我就要根據其子節點的值更新其idx的值,然後再往上更新其父親節點的值,當碰到idx的值大於我更新的那個值時,就可以退出更新了,因為後面的都是一樣的。

void modify(int p,int v)

}}

遍歷其子節點的依據是:

for(int j = 1; j < lowbit(i); j<<=1)
根據樹狀陣列的二進位制原理。

參考:樹狀陣列求區間最值

樹狀陣列詳解

**:

#include #include #include #include using namespace std;

#define max(a,b) ((a)>(b))?(a):(b)

#define max_ 200010

#define n 1000010

int a[max_], idx[max_];

int n;

int lowbit(int x)

void init() }}

void modify(int p,int v) }}

int query(int l,int r)

} return ans;

}int main()

init();

for( i = 0; i < m; ++i)

} }return 0;

}

hdu 1754 I Hate It (線段樹版)

讀入的時候因為要先輸入字元c,所以要用getchar 和輸入時的 c處理掉空格,很煩,不按字元輸入而是 s輸入字串可避免這個問題 include include using namespace std define lson l,m,rt 1 define rson m 1,r,rt 1 1 def...

hdu1754 I Hate It 線段樹模板

很多學校流行一種比較的習慣。老師們很喜歡詢問,從某某到某某當中,分數最高的是多少。這讓很多學生很反感。不管你喜不喜歡,現在需要你做的是,就是按照老師的要求,寫乙個程式,模擬老師的詢問。當然,老師有時候需要更新某位同學的成績。本題目包含多組測試,請處理到檔案結束。在每個測試的第一行,有兩個正整數 n ...

HDU 1754 I Hate It 線段樹模板

本題目包含多組測試,請處理到檔案結束。在每個測試的第一行,有兩個正整數 n 和 m 0多組測試,存在單點更新和區間查詢,維護區間最大值,不需要加標記,普通的線段樹模板。include include include include include using namespace std const ...