3262 陌上花開 樹狀陣列套平衡樹 CDQ分治

2021-07-10 05:24:00 字數 2721 閱讀 4461

就是解決乙個三維偏序問題,可以用樹套樹來解決。

第一維排序,第二維放到樹狀陣列裡,每個樹狀陣列下建平衡樹維護第三維。

我們按第一維排序後從小到大加入,每次到乙個點時就把樹狀陣列中小於等於第二維的掃一遍,再找平衡樹里小於等於第三維的,這樣就可以了。

我們還可以用強大的cdq分治來解決。

同樣是第一維排序,然後第二維分治,第三維樹狀陣列。 定義s

olve

(l,r

) 為求出按照第一維排序後的區間[l

,r] 對答案的貢獻。

那麼每次我們首先遞迴呼叫so

lve(

l,mi

d)和sol

ve(m

id+1

,r) ,然後考慮區間[l

,mid

] 對區間[m

id+1

,r] 的影響,我們回溯的時候按照第二維進行歸併排序,這樣保證呼叫完兩個子過程時,區間[l

,mid

] 和區間[m

id+1

,r] 中第二維是有序的,而區間[l

,mid

] 中的任何一點比區間[m

id+1

,r] 中的任何一點的第一維也小,這樣保證了前兩維都有序。我們就用第三維維護樹狀陣列,每次掃到區間[m

id+1

,r] 中的一點p2

時,就把區間[l

,mid

] 中第二維比p2

第二維小的p1

的第三維加入樹狀陣列,然後再統計當中比p2

第三維小的答案。就線性求出了區間[l

,mid

] 對區間[m

id+1

,r] 的貢獻。

樹狀陣列套平衡樹

#include

#include

#include

#define m 5000005

#define n 100005

#define lowbit(i) (i&(-i))

using

namespace

std;

int n,k,cnt,tmp;

int root[n<<1],ans[n],sum[n];

struct node a[n];

int size[m],same[m],ls[m],rs[m],rnd[m],val[m];

inline

int read()

while (c>='0'&&c<='9')

return a*f;

}inline

bool cmp(node a,node b)

inline

void lturn(int &k)

inline

void rturn(int &k)

void insert(int &k,int v)

size[k]++;

if (v==val[k]) same[k]++;

else

if (vif (rnd[ls[k]]else

else

if (velse tmp+=size[ls[k]]+same[k],getrank(rs[k],v);

}inline

void query(int x,int val)

inline

void add(int x,int val)

int main()

add(a[i].b,a[i].c);

}for (int i=0;iprintf("%d\n",ans[i]);

return

0;}

cdq分治:

#include

#include

#include

#define n 200005

#define lowbit(i) (i&(-i))

using

namespace

std;

int n,k,cnt;

struct node a[100005],p[100005],np[100005];

int tree[200005],ans[100005];

inline

int read()

while (c>='0'&&c<='9')

return a*f;

}inline

bool cmp1(node a,node b)

inline

int query(int x)

void solve(int l,int r)

p[p2].ans+=query(p[p2].c);

p2++;

}for (int j=l;j1;

for (int i=l;i<=r;i++)

if ((cmp0(p[p1],p[p2])||p2>r)&&p1<=mid) np[i]=p[p1++]; else np[i]=p[p2++];

for (int i=l;i<=r;i++) p[i]=np[i];

}int main()

}solve(1,cnt);

for (int i=1;i<=cnt;i++) ans[p[i].ans+p[i].total-1]+=p[i].total;

for (int i=0;iprintf("%d\n",ans[i]);

return

0;}

BZOJ 3262 陌上花開 「樹套樹」

三維空間內求每個點比它3維都要大的點的個數。第1維排序,第2維樹狀陣列,第3維treap。好像第1維排序就叫做降維了?神tm吧乙個陣列開錯大小老wa。cdq分治好像挺好寫 include include using namespace std int read const int n 100005,...

BZOJ 3262 陌上花開 樹套樹

蒟蒻不會什麼cdq分治,treap套樹狀陣列寫好。看來還是有必要學一下cdq分治,逼近總不能每次拿著平衡樹亂套啊!這道題大致思路就是排序 樹狀陣列 treap,明了!include include include include include using namespace std const i...

bzoj3262 陌上花開 樹套樹

1 include 2 include 3 include 4 include 5 include 6 define maxn 100005 7 define maxm 200005 8 define maxk 2000005 9using namespace std 1011 int n,k,te...