題面
最近公尺娜都在學cdq分治,看到題都直接想cdq,還講得頭頭是道,所以本蒟蒻也水一水。找到bzoj的一題果題,居然還是許可權的,但我還是找到了本題。
個人理解,有乙個修改和查詢的序列,cdq就是可以離線的條件下,用logn的複雜度,把動態的問題轉化為靜態的問題,即把邊修改邊查詢改為先修改再查詢。
主要思想大概是這樣的,有乙個詢問和查詢的序列區間[l,r],二分乙個mid,先處理子問題[l,mid],再用與(r-l)相關的複雜度,處理[l,mid]中的修改對[mid+1,r]中的詢問的影響,然後再處理區間[mid+1,r]。
題意就是有n個元素,每個元素有3個屬性a,b,c。對於每乙個元素問有多少個其他元素的3個屬性都分別小於等於它的三維。
二維就是乙個bit求逆序對。
三維還是要先排序,然後套cdq分治,現在有兩個區間[l,mid],和[mid+1,r],由於[mid+1,r]的第一維都大於[l,mid],問題就變成了對於[mid+1,r]的每乙個元素,[l,mid]有多少個元素的兩維都小於它,就是乙個權值bit可以搞定了。
看起來非常簡單,但我剛看到題的時候還是懵b的,聽旁邊的某犇吹了一會b才會一丟丟。
但這題是小於等於,並不是嚴格小於,原則上應該用兩個陣列,加入bit時應把相同的都加進去再統計答案。但經過我的玄學思考,發現只要每次都按3關鍵字排序,就能解決大部分問題,但還有三維都相同的情況沒有考慮。
顯然三維相同答案必然也相同,而3關鍵字排序必然時它們排到了一起。可以由前到後去max,再由後往前去max,也許就可以了。
但還是wa了,通過玩爐石,我發現了這可能是因為快排的不穩定性使得所有3維相同的元素的答案都不是正確答案,那麼再人為控制排序的穩定性就可以a了。
複雜度大概是這樣的
f(n)=f(n/2)*2+nlog n=n(logn)^2
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
#define mmst(a, b) memset(a, b, sizeof(a))
#define mmcp(a, b) memcpy(a, b, sizeof(b))
typedef
long
long ll;
const
int n=100100;
struct yy
f[n],g[n];
bool amp(yy x,yy y)
int sum(int x)
void work(int l,int r)
int main()
sort(f+1,f+n+1,amp);
for(int i=1;i<=n;i++)
f[i].now=i;
work(1,n);
for(int i=2;i<=n;i++)
if(f[i].a==f[i-1].a&&f[i].b==f[i-1].b&&f[i].c==f[i-1].c)
ans[f[i].num]=max(ans[f[i].num],ans[f[i-1].num]);
for(int i=n-1;i>=1;i--)
if(f[i].a==f[i+1].a&&f[i].b==f[i+1].b&&f[i].c==f[i+1].c)
ans[f[i].num]=max(ans[f[i].num],ans[f[i+1].num]);
for(int i=1;i<=n;i++)
h[ans[i]]++;
for(int i=0;iprintf("%d\n",h[i]);
return
0;}
洛谷3810 三維偏序
對於n個元素,第i個元素有ai,bi,ci三個屬性,f i 表示滿足aj ai,bj bi,cj ci的j i不等於j 的個數,對於在區間 0,n 1 的d,輸出f i d的i的數量。n 100000 10 3 3 3 3 2 3 3 2 3 1 3 1 1 3 1 2 1 3 1 1 1 2 1 ...
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 ...