多維關係基本上指偏序關係,即乙個元素包含多個屬性\((a,b,..)\),每次需要快速查詢滿足某一關係的所有元素,再進行整體處理(權值和,第\(k\)大...),如最基本的逆序對,每乙個元素包含了位置和權值\((pos,val)\),對於每乙個\(i\),需要查詢的是滿足\(pos_ja_i\)的\(j\)的個數。
在處理這類問題的時候,首先需要將題目包含的關係找到,再運用各種方法,不斷消除偏序關係,最終使滿足條件的元素在乙個可以整體處理的資料結構中,就可以很好的解決了。
下面就將介紹一些消除偏序關係的方法。
沒錯,最簡單的方法就是排序。
設偏序關係是\(a_i(下同),那我們就按\(a_i\)降序排序,這樣當處理\(i\)的時候,所有\(a_j>a_i\)的\(j\)就已經被處理好了,這時候我們就消去了\(a\)這一偏序關係。
當然,如果偏序關係是\(a_(保證\(a_\le a_\le a_\))的時候,我們按\(a_\)排序後,可以滿足\(a_,但\(a_的怎麼滿足呢?其實只要在刪除\(a_的\(j\)就可以了。或許你已經聽過這個思想,它還有另外乙個名字——掃瞄線。
排序可以消除一維關係,剩下一維整體處理,但往往題目中的偏序關係不止兩維,這時候就需要更高階的方法了。
kdt是用來處理在\(k\)維空間上,維護單點的二叉樹/線段樹結構。核心是將點進行不斷劃分,使整顆樹的深度為\(o(\log n)\)級別,對乙個矩形查詢/修改一次的複雜度為\(o(n^})\)。
建樹:選擇方差最大的乙個維度(注意方差計算時開double
),然後以該維度上的中位數劃分當前區間,即將小於(等於)的放在左邊,大於(等於)的放右邊。然後遞迴處理。pushup
的時候維護包含所有點的最小矩形的邊界。
查詢/修改:正常修改,即當前矩形範圍被詢問矩形包含即操作,返回,完全不包含的情況就返回。然後由於某種奇妙的性質,整個過程的複雜度為\(o(n^})\)
兩種不同的結構
特點:樹套樹,即在樹型資料結構的每乙個節點上再開乙個樹型資料結構。在第乙個資料結構的處理中刪掉第乙個偏序關係,而第二個資料結構進行整體處理。
先說明一下內層與外層的最主要的區別:我們需要在多個獨立的內層資料結構中得到結果並合併起來,所以不能處理第\(k\)大之類的問題。所以一定要選擇好先消除哪個偏序關係,留下哪個做處理。
內層可以處理所有單點,區間問題,在處理區間問題時注意標記永久化,可以極大減小常數。
在有重點的情況下,處理比較困難。
有值域限制,而且空間為\(o(n\log^2 n)\)。
外層和內層基本一致,處理此處標記無法下傳,所以必須標記永久化。
平衡樹樹套樹與kdt的比較
實際問題
怎麼理解這句話?
就好比這樣乙個問題:
有乙個陣列,數軸上有一些點,多次詢問,每次詢問給定乙個區間,求區間所包含的點數。如果提前告訴你所有的點,然後再去詢問。這時候你知道,所有的點都可能會在區間中,就可以將點按座標排序,在區間左端點後、右端點前的就在區間內。
但如果在詢問之後又加了一些點,並且後面還有詢問...這時候上面的辦法就沒用了,因為在詢問後加入的點不可能前面的詢問矩形內。這時候你按座標排序,在區間左端點後、右端點前的點不一定在區間內。
上面這兩種情況就分別對應了靜態和動態(你也可以理解為動態情況多了時間軸的偏序關係,即只有時間前的才能貢獻時間後的,這也是為什麼我將cdq放在了這個專題裡)
其他:排除最明顯的\(a_i。
若遇到更多的應該會新增。
做這類題的大概步驟就是:找到題目裡的偏序關係\(\rightarrow\)選用合適的演算法\(\rightarrow\)一定要對拍!
處理多維陣列
在實際工作,我們經常會遇到對多維陣列的處理,一般就會採用多重迴圈的方式,直到陣列的最裡面那一層或者使用遞迴來處理,在php中可以使用array walk recursive來靈活處理 desc 處理多維陣列 param array data 待處理資料 param array field 處理字段陣...
多維度條件情況處理
設計程式的時候,多維度條件情況處理 對於多維條件的限制時,可以先只考慮乙個主要的條件,然後看怎麼在這這條件中植入其他維度的條件 比如下面的 是以根為乙個重複單元 根及其緊下一層 迭代維度 1,以最大根 100000 為開始迭代,每迭代一次處理乙個根,進入下乙個根 動態變化的根 2,處理每個根的時候,...
多維資料集和關聯式資料庫的關係
在處理 microsoft sql server 2005 analysis services ssas 多維資料集和維度時,可以使用現有關聯式資料庫來設計多維資料集和維度,也可以先設計多維資料集和維度,然後使用架構生成嚮導基於您所設計的多維資料集和維度為基礎主題區域資料庫生成架構。analysis...