這是我第一次接觸樹形陣列,剛開始看題的首先想法,是o(n2)的樸素演算法,但是看到n是105 就放棄了...最後實在想不到什麼好的方法,上網一搜發現時樹形陣列,之前只是聽說過,連它是做什麼的都不知道...
然後花了一晚上去搜尋屬性陣列的知識,發現了一片比較好理解的文章,轉到了我這裡,位址是http://blog.csdn.net/titikdhu/archive/2010/07/21/5751887.aspx。
好了,轉來說這道題吧~其實我感覺即使知道要用樹形陣列的話,具體的實現方法也不好想...他是先以結束位置ed為關鍵字進行公升序排序,若結束位相同,則以起始位st為關鍵字進行降序排序。然後對所有的區間進行逆向遍歷(即從最後乙個開始,倒序)。最終想要達到的效果是,由於是逆向遍歷,所以保證了cows[i+1].ed>=cows[i].ed,故要判斷兩頭牛的強壯與否只需判斷兩者的st。其實這裡引用了樹狀陣列的資料結構和這種排序(也是種離散化)不無關係。
現假設有大小兩個區間,且大區間的結束位大於等於小區間的結束位。我們先判斷的是大區間,然後將該區間的起始位st之後的區間求和+1,即表示該區間上有一頭牛,當有乙個小區間存在,若小區間的st小於大區間的st,則表示兩頭牛是相交的無法判斷誰強壯,而且這時對小區間st之前的位置進行求和由於大區間的st大於小區間st,故求和值肯定為0,表示沒有比該校區間的牛更強壯的牛,符合假設;若小區間的大於等於大區間的st,即表示小區間完全包含在大區間中(這裡先不考慮兩區間完全相同的情況),這時對小區間起始位st之前進行求和,由於有大區間st的存在,所以求和為1,即表示有一頭牛比當前小區間的牛強壯。類似的這是兩個區間的比較,可以繼續拿小區間和其他的大區間比較(當然是在大區間的結束位大於等於小區間的結束位的前提下),比較和這個類似。由於我們實現進行了排序,所以現在的序列歷經符合了我們「大區間的結束位大於等於小區間的結束位」的要求,故可以直接像上面敘述的一樣判斷,不必要考慮很多,其實就是兩兩的比較,只不過那些大區間在小區間出現之前都已經標記好了,只需小區間對其起始位st之前進行求和,即判斷有幾個大區間包含他(即比他強壯)即可。
其實說了這麼一大推,只是我這個不了解樹狀陣列的新手初次接觸時候的不明白,我發現網上的很多介紹樹狀陣列的文章都比較抽象,上來就是二進位制...對於新手來說一張圖可能勝過十行解釋,所以要是初次接觸的話,我還是覺得上面那個鏈結的文章比較適合。
附上**(sicily上居然進了這題的第一版~有些意料之外):
題目1088 剩下的樹
題目描述 有乙個長度為整數l 1 l 10000 的馬路,可以想象成數軸上長度為l的乙個線段,起點是座標原點,在每個整數座標點有一棵樹,即在0,1,2,l共l 1個位置上有l 1棵樹。現在要移走一些樹,移走的樹的區間用一對數字表示,如 100 200表示移走從100到200之間 包括端點 所有的樹。...
POJ 2481 Cows(線段樹單點更新)
兩個區間 si,ei 和 sj,ej 0 s e 10 5 若 si sj,且 ej ei 且 ei si ej sj,則第i個區間覆蓋第j個區間,即牛i比牛j強壯。問對於每一頭牛i有多少頭牛比它強壯。這題先一看,不知如何下手。首先,將每個區間的s和e當做是 s,e 乙個點,這樣子把所有點在座標系上...
POJ 2481 Cows 線段樹 樹狀陣列
給出n個區間 輸出每個區間 是多少個區間的真子集 思路 區間左端點為第一關鍵字,右端點第二關鍵字,前者公升序後者降序 這樣對每個區間i,只需要查詢 ri到n有多少個右端點就是答案,可能有好幾個區間相同,那麼預處理一下最後減掉完全相同的區間即可 include include include incl...