傳送門
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 ...