bzoj 3674 可持久化並查集)

2021-09-19 04:32:11 字數 1500 閱讀 6340

傳送門

題解:一道可持久化並查集的裸題,板子子對了就能過;

可持久化並查集是基於主席數的一種結構,可持久化並查集要求能夠訪問歷史版本,跟主席樹很像,所以可以通過主席樹維護普通並查集的fa陣列,但是由於用主席樹維護後沒有辦法用路徑壓縮,所以需要採用新的合併方式——啟發式合併,對每乙個節點增加乙個level,每次合併從小的指向大的,如果合併的兩個節點的level相等,則合併後的節點的level需要增加,據傳說與路徑壓縮的複雜度相同;

ac**:

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

const int maxn=2e5+5;

inline int read()

struct node;

node tree[maxn*20];

int ti[maxn],tot,n,m;//ti記錄版本的首節點

inline int build(int l,int r)

int mid=(l+r)>>1;

tree[now].lson=build(l,mid);

tree[now].rson=build(mid+1,r);

return now;

}//建樹

inline int newpoint(int lst,int l,int r,int x,int fa)

tree[now].lson=tree[lst].lson;

tree[now].rson=tree[lst].rson;

if(x<=mid)

tree[now].lson=newpoint(tree[lst].lson,l,mid,x,fa);

else

tree[now].rson=newpoint(tree[lst].rson,mid+1,r,x,fa);

return now;

}//更新節點

inline void add_level(int now,int l,int r,int x)

if(x<=mid)

add_level(tree[now].lson,l,mid,x);

else

add_level(tree[now].rson,mid+1,r,x);

}//增加level

inline int query(int now,int l,int r,int x)//查詢當前版本x所在位置

inline int getfa(int now,int x)//得到當前版本x父親的節點位置

inline void connect(int &t,int x,int y)//合併兩個聯通塊

int main( )

else if(k==2)

else

}}

BZOJ 3674 可持久化並查集

3674 可持久化並查集加強版 time limit 15 sec memory limit 256 mb submit 4051 solved 1503 submit status discuss description description 自從zkysb出了可持久化並查集後 hzwer 亂寫...

bzoj 3674 可持久化並查集加強版

description 自從zkysb出了可持久化並查集後 hzwer 亂寫能ac,暴力踩標程 kuribohg 我不路徑壓縮就過了!ndsf 暴力就可以輕鬆虐!zky bzoj 3673的加強版。就沒了。include using namespace std const int n 200000 ...

BZOJ 3674 可持久化並查集加強版

題意 三種操作 1 合併ab所在集合 2 查詢ab是否在乙個集合 3 狀態回到第x個操作之前。思路 1 每個節點儲存乙個深度 合併時找到兩個節點的根,ra,rb,若ra的深度小,則ra的父親設為rb,否則rb的父親設為ra 2 查詢直接找到兩個的根。這個的複雜度是多少呢?貌似是logn logn。每...