1. 程式人生 > >多維偏序

多維偏序

復雜度 等於 eset 這位 esc open nbsp 指針 +=

一般情況下,我們比較一個數大小,就是ai>aj即可,

而在上升子序列中,當i>j並且ai>aj的時候,才可以認為i這位的數大於j這位的數。

這就是一個二維偏序。

類似的,有n個數,每個數m個屬性,一個數比另一個數大,當且僅當這個數的所有屬性都大於另一個數。

這就是一個m維偏序。

對於三維偏序,可以用cdq分治、排序、樹狀數組處理。

luogu P3810

Description:

n 個元素,第 i 個元素有 ai?bi?ci? 三個屬性,設 f(i) 表示滿足 aj?ai?bj?bi?cj?ci?j 的數量。

對於d[0,n) ,求 f(i) = d的數量

Solution:

三維偏序的模板題。

我們先按照a從小到大排序,

然後cdq分治。

先遞歸到兩邊,

回溯到這一層之後,把左兒子的所有的數按照b排序,右兒子的所有數也按照b排序。

這樣,左兒子的數之間雖然a不一定遞增,但是因為開始按照a排序,所以左邊所有的數的a一定都小於右邊的數。

b排好序之後,

兩個指針j,i分別從1~mid,mid+1~r 即左右兒子區間的起止點開始走,,

對於右邊的一個數i,當j的數的b值不大於i的b值時,不斷向後走j,並且把這些數的c值放進一個樹狀數組裏,

當j的b值大於i之後,當前所有左兒子裏面,b小於i這個數的數的c屬性都放進樹狀數組裏了。

只有放進去的這些數才可能來更新f值。

在i向後走之前,f[a[i].ans]+=query(a[i].z),滿足第三個條件的數也找到了。

就把所有當前這個層裏面,符合條件的數都找出來了。

由於cdq分治,會把i之前的所有的數都分成logn個區間,更新完f[i]了。

大家可以手動畫圖,或者模擬一下。

復雜度:nlogn^2

那麽,這個

註意因為是小於等於號,所以我們先

多維偏序