線段樹主要的優(yōu)勢是在將一個線性的數(shù)組轉(zhuǎn)換成一棵樹,從而減少大量的重復(fù)操作,并且在樹中的節(jié)點保存一些信息,以便更好的統(tǒng)計!它的各個操作的復(fù)雜度都是在logn的,而且我們知道,對于n個節(jié)點來說,最多是只有2n-1個樹的節(jié)點,另外對于一個如果有maxn個節(jié)點,那么我們知道最多要用4*maxn個樹的節(jié)點,這個可以證明

Poj2828 插入隊列,在這個過程中,后一個人可能會覆蓋前一個人,那么如何用線段樹來解呢,我們知道線段樹的葉子節(jié)點代表的就是當(dāng)個節(jié)點的值,這里,我們把樹的節(jié)點表示空位的大小,那么在他插入的時候,然后從后面開始插入,那么如果前面出現(xiàn)重復(fù)的,那么因為空位數(shù)減少了,那么他們也會插在后面,插入的根據(jù)是根據(jù)空位的大俠來的,這個更新可以這樣寫

 Void update(int p,int l,int r,int rt)

{

  當(dāng)前節(jié)點的空位數(shù)減少1

  如果p此時比他左孩子節(jié)點的空位數(shù)大,那么在往有孩子插入,此時空位數(shù)p-tree[mid].v

  否則,遍歷左孩子
}

Hdoj 1754 要求的是一段區(qū)間的最大值,這個在更新的時候,要不斷更新父子節(jié)點,另外在查詢的時候,其實對于每一次,最后的來的值總是從葉子節(jié)點的來的,只不過利用二分的思想,讓他每次都舍棄了一半的選擇!

code

Hdoj1698 hook,這題是用了懶惰標(biāo)記,要求的問題是在一段區(qū)間了進(jìn)行了某一個操作,然后求整個操作后,總共的和是多少

 懶惰的標(biāo)記是指如果在更新的過程中,父子節(jié)點已經(jīng)被全部覆蓋,那么作為他的孩子節(jié)點也坐上同樣的標(biāo)記,這個思想是可以用這樣,首先判斷當(dāng)前節(jié)點有沒被完全覆蓋,若是,則進(jìn)行懶惰標(biāo)記,對于他的所有孩子節(jié)點都是如此

code

Hdoj 3577這題的大意就是 火車有k個座位,乘客可以買從ab的車票,給你一些乘客的買票需求,要你求的就是哪些乘客能夠買到票 

  這題用的是線段樹,我們知道最好的情況是在每一條路線上能夠充分的用上,也就是被完全覆蓋,那么在判段許可的時候,如果此段已經(jīng)被覆蓋過,那么不行!這里有一個問

題就是,因為有多個座位,所以每個座位都有一條路線,然后按照上述的思想進(jìn)行處理即可

問題:第一次wa,是因為這里沒注意更新的區(qū)間應(yīng)該是[a,b-1],因為我到了b站之后,就從這站下來了,然后下一次是可以從b站出發(fā)的 

code

Poj2528 這一題就是一些海報,要求的是最后沒有被完全覆蓋的海報總數(shù), 那么怎么求呢,一個問題就是如果我們按照從一開始的數(shù)據(jù)進(jìn)行處理的話,那么前一張海報可能會被后一張海報完全覆蓋,那么最后的結(jié)果就無法有效求出,那么我們可以反過來,那就是從最上面的海報開始,那么判斷這段區(qū)間內(nèi)是否已經(jīng)被完全覆蓋過,若是,則不用加1,否則加1

 這題先用離散化,將大的數(shù)據(jù)映射到比較小的數(shù)字上面,然后,根據(jù)離散后的數(shù)據(jù)我們可以得出,現(xiàn)在的問題就是,如何求,才能夠去掉被完全覆蓋的區(qū)間,那么這里我們建立一個hash,這個hash存放的值是表示第i個海報,如果查詢的當(dāng)前的節(jié)點的記錄值,在hash表里沒有被記錄過,那么說明此區(qū)間沒有被完全覆蓋,

 現(xiàn)在證明這樣做的正確性,首先如果前一張海報被后一張覆蓋的情況,那么由于更新后的cnt[]的域記錄的也是后一張海報的離散化值,那么就不會記錄錯誤

  總結(jié)上面的過程,這個題目的總體思路就是輸入數(shù)據(jù)后,離散處理,在針對每一個進(jìn)行更新,最后查詢,代碼待更新。。