學習筆記 可持久化並查集(BZOJ3673)

2021-09-05 11:41:01 字數 1462 閱讀 3867

好久之前就想學了 然後今天恰巧一道題需要用到就學了

前置芝士

1.主席樹[可持久化陣列]

2.並查集

如果你掌握了前面兩個那麼這個東西你就會覺得非常沙茶。。

構造可持久化並查集 = 主席樹  + 並查集

有點蠢= =

當然 我們這裡的並查集是要按秩合併的並查集

[按秩合併:就是把dep小的連線到大的上面 這個複雜度分析出來是o(lgn)的 原因不要問我 我不知道= =]

不可以路徑壓縮 原因好像是可以被極限資料卡掉?[我也不知道路徑壓縮了你怎麼訪問歷史版本的emm。。]

這樣的話 我們每次開log個節點連下來 然後對於每個點維護fa和dep就可以了

然後dep的更新就是 當兩個高度一樣的時候 連起來那麼被連的深度需要+1

就沒了qwq。

例題就是bzoj3673 真·模板

**。

#include#include#include#include#define inf 20021225

#define ll long long

#define mxn 200010

#define pa pair#define mp make_pair

using namespace std;

struct nodet[mxn*40];

int cnt,rt[mxn],n;

void build(int &x,int l,int r)

int mid=l+r>>1;

build(t[x].ls,l,mid); build(t[x].rs,mid+1,r);

}void insert(int &x,int lt,int l,int r,int d,int fa)

int mid = l+r>>1;

if(d<=mid) insert(t[x].ls,t[lt].ls,l,mid,d,fa);

else insert(t[x].rs,t[lt].rs,mid+1,r,d,fa);

}void update(int x,int l,int r,int d)

int mid = l+r>>1;

if(d<=mid) update(t[x].ls,l,mid,d);

else update(t[x].rs,mid+1,r,d);

}int query(int x,int l,int r,int d)

int find(int root,int x)

int main()

scanf("%d",&y); rt[i]=rt[i-1];

int fx = find(rt[i],x),fy = find(rt[i],y);

if(opt==1)

}else printf("%d\n",t[fx].fa==t[fy].fa);

} return 0;

}

學習筆記 可持久化並查集(BZOJ3673)

好久之前就想學了 然後今天恰巧一道題需要用到就學了 前置芝士 1.主席樹 可持久化陣列 2.並查集 如果你掌握了前面兩個那麼這個東西你就會覺得非常沙茶。構造可持久化並查集 主席樹 並查集 有點蠢 當然 我們這裡的並查集是要按秩合併的並查集 按秩合併 就是把dep小的連線到大的上面 這個複雜度分析出來...

可持久化並查集

n個集合 m個操作 1 a b 合併a,b所在集合 2 k 回到第k次操作之後的狀態 查詢算作操作 3 a b 詢問a,b是否屬於同一集合,是則輸出1否則輸出0 所給的a,b,k均經過加密,加密方法為x x xor lastans,lastans是上一次的輸出答案 並查集實質是乙個陣列,可持久化並查...

可持久化並查集

可持久化陣列 可持久化陣列是一種可以回退,訪問之前版本的陣列 是一些其他可持久化資料結構的基石 例如可持久化並查集 與普通並查集不同的是 這裡用到了 按秩合併新增鏈結描述 include const int n 2e5 7 int rootfa n rootdep n cnt,tot struct ...