頭疼的模板 三維偏序(陌上花開)

2022-05-26 20:30:12 字數 1998 閱讀 1992

這道題是zyd在濟南三期qbxt講bitset的時候提到的,不過我好像當時秒了正解的樣子。。。

\(*************************==分割線******************************==\)

其實cdq分治的思想與應用都能被很簡單地描述——它是用來解決各種區間段轉移問題\(x -> y (x < y)\)的一種演算法。

我們用f[x]表示位置x轉移之後的結果,用solve(l,r)來傳遞完全限制在[l,r]範圍內的狀態轉移,並且轉移\(a->b\)一定有\(a

那麼對於solve(l,r)

1.可以把這些問題排成乙個序列,用乙個區間[l,r]表示。

2.分。遞迴處理左邊區間[l,m]和右邊區間[m+1,r]的問題。

3.治。合併兩個子問題,同時考慮到[l,m]內的修改對[m+1,r]內的查詢產生的影響。即,用左邊的子問題幫助解決右邊的子問題

這樣cdq分治就做完啦

那cdq有什麼好處呢?

cdq分治是我們處理各類問題的重要**

它的優勢在於可以頂替複雜的高階資料結構,而且常數比較

缺點在於必須離線操作。

我們考慮一下,這道題的要求是求三維偏序,但是好像cdq分治只能求二維偏序的樣子qwq。。。

所以我們先在cdq分治之前,把其中1維變成有序的,然後再分治下去,這時在區間\([l,mid]\)關於區間\([mid + 1,r]\)就不存在某一維的逆序了,所以就只剩下2維,於是就將三維偏序成功的轉化為可以用cdq分治來解的二維偏序問題。

這個時候來一波樹狀陣列求逆序對的操作搞一下二維偏序,就可以把跨過中線的,左邊更新右邊的情況計算出來,然後左右兩邊遞迴處理就好了。。。

注意:只計算左邊的操作對右邊的詢問的貢獻!!!

時間複雜度 : 分治 + 樹狀陣列 = \(o(nlog^2 n)\)

#include#include#include#include#includeusing namespace std;

const int n = 200100;

struct qaq

inline bool operator < (const qaq &b) const

}a[n],c[n];

int m,n,ans[n],opt[n];

inline int lowbit(int x)

inline bool cmp(qaq a,qaq b)

void print(int x,int y)

}int gets(int x)

return sum;

}void clean(int x)

}void cdq(int l,int r)

a[j].p += gets(a[j].z);

} for(int i = l ; i <= mid ; i++) clean(a[i].z);

for(int i = l ; i <= r; i++) c[i] = a[i];

i = l; int j = mid+1;

for(int k = l ; k <= r ; k++) else a[k] = c[j++]; }}

int main()

sort(a+1,a+n+1,cmp);

cdq(1,n);

sort(a+1,a+n+1,cmp);

int i = 1;

while(i <= n)

for(int i = 0 ; i < n ; i++)

printf("%d\n",ans[i]);

return 0;

}

三維偏序(陌上花開)

這是一道模板題 可以使用bitset,cdq分治,k dtree等方式解決。有 n個元素,第 i個元素有 ai bi ci 三個屬性,設 f i 表示滿足 aj ai 且 bj bi 且 cj ci 的 j 的數量。對於 d 0,n 求 f i d 的數量 輸入格式 第一行兩個整數 n k,分別表示...

三維偏序 陌上花開

有 n 個元素,每個元素有三個屬性 a i b i c i 定義 f i 為滿足 a j a i 且 b j b i 且 c j c i 的 j 的個數 ans i sum f j i 求所有的 ans i 陌上花開,心憂梓桑。cdq 分治模板題 首先以 a 為關鍵字排序,省略一維 再以 b 為關鍵...

陌上花開(三維偏序)(cdq分治)

其實就是三位偏序的模板,cdq分治入門題。學習cdq分治請看 stdcall大佬的部落格 傳送門 排序來維護第一層,cdq維護一層,樹狀陣列維護一層,然後就沒有啦qwqwq include include include include include define maxn 100010 usin...