P3810 模板 三維偏序(陌上花開)

2022-05-20 02:26:24 字數 1517 閱讀 5838

傳送門

cdq分治

先三關鍵字排序

然後把第二關鍵字歸併排序

在合併子區間時用 第三關鍵字的權值樹狀樹組 算出子區間的答案

為什麼可以這樣搞呢

首先第一維已經有序

所以只要考慮左邊對右邊的影響

把第二維歸併時 左子區間的第一二關鍵字 全部小於或等於 右子區間的第一二關鍵字

所以也只要考慮左邊對右邊的影響

就用 第三關鍵字權值樹狀樹組 搞一搞 二維偏序 就好了

二維偏序應該懂吧,實現和細節還是看**吧

還要注意有重複的數

#include#include

#include

#include

#include

using

namespace

std;

inline

intread()

returnx;}

const

int n=4e5+7

;int

n,m;

inta[n],b[n],c[n],p[n],cnt[n],ans[n],v[n];

//a,b,c為三個關鍵字,p存排序去重後的資料,這裡沒用結構體,可以省空間

//v是每個數重複的數量

inline bool cmp1(const

int &x,const

int &y)

//不用結構體排序的騷操作

int t[n];//

數狀陣列

inline void add(int x,intv)}

inline

int query(int

x)

return

res;

}int tmp[n];//

歸併時的臨時陣列

void cdq(int l,int

r)//

核心,樹狀陣列維護二維偏序

while(j<=r) cnt[p[j]]+=query(c[p[j]]),tmp[++tot]=p[j],j++;

while(i<=mid) tmp[++tot]=p[i],i++;

//可能還有一些沒處理完

int mx=b[p[r]];

for(i=l; i<=mid&&b[p[i]]<=mx ;i++) add(c[p[i]],-v[p[i]]);//

用完要這樣清空

for(i=l;i<=r;i++) p[i]=tmp[i-l+1];//

歸併排序

}int

main()

v[p[tot]]++;

//去重並計算重複的數量

cdq(

1,tot);

for(int i=1;i<=tot;i++) ans[cnt[p[i]]+v[p[i]]-1]+=v[p[i]];//

注意有重複的數字

for(int i=0;i"

%d\n

",ans[i]);

return0;

}

P3810 模板 三維偏序(陌上花開)

傳送門 洛谷 哇塞大佬好厲害 據說正解是一維排序,二維cdq,三維樹狀陣列的 然而大佬硬是二維三維都用了cdq 而且莫名好寫 太暴力了 1 minamoto 2 include3 include4 include5 using std sort 6 define getc p1 p2 p2 p1 b...

P3810 模板 三維偏序(陌上花開)

這是一道模板題 可以使用bitset,cdq分治,k dtree等方式解決。有 nn 個元素,第 ii 個元素有 a iai b ibi c ici 三個屬性,設 f i f i 表示滿足 a j leq a iaj ai 且 b j leq b ibj bi 且 c j leq c icj ci ...

P3810 模板 三維偏序(陌上花開)

有 nn 個元素,第 ii 個元素有 a iai b ibi c ici 三個屬性,設 f i f i 表示滿足 a j leq a iaj ai 且 b j leq b ibj bi 且 c j leq c icj ci 的 jj 的數量。對於 d in 0,n d 0,n 求 f i df i ...