洛谷 P3402 可持久化並查集

2021-09-11 18:49:56 字數 1199 閱讀 2565

解題思路:

可持久化並查集也就是可持續化線段樹 + 並查集 == 主席樹  + 並查集

像我們平常做的並查集都是路徑壓縮,但因為要保證可持續化,所以資訊不能改變,所以我們採用啟發式合併來合併集合。

啟發式合併的樹最高深度不會超過log(n)+1。因為深度為2的樹需要兩個點,那麼深度為3的需要兩個深度為2的也就是2*2==4個點。所以2^n次方個點最深可以到log(n)+1。

所以主席樹每個點就需要維護他的父親和它為根的樹的深度。而且只需要維護區間為1的節點就可以了。

#include#define inf 0x3f3f3f3f

#define lson l,mid,s[rt].ls

#define rson mid+1,r,s[rt].rs

using namespace std;

typedef long long ll;

const int mx = 2e5 + 10;

const int mod = 1e9+7;

const ll inf = -1e16;

int n,m,siz,root[mx];

struct node

s[mx*30];

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

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

build(lson);build(rson);

}node query(int l,int r,int rt,int p)

node find(int rt,int x)

}void merge(int l,int r,int& rt,int x,int p,int fa)

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

if(p<=mid) merge(lson,s[x].ls,p,fa);

else merge(rson,s[x].rs,p,fa);

}void add(int l,int r,int rt,int p)

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

if(p<=mid) add(lson,p);

else add(rson,p);

}void update(int a,int b,int i)

int main()

else if(c==2)else

} return 0;

}

洛谷P3402 模板 可持久化並查集

n個集合 m個操作 1 a b 合併a,b所在集合 2 k 回到第k次操作之後的狀態 查詢算作操作 3 a b 詢問a,b是否屬於同一集合,是則輸出1否則輸出05 6 1 1 2 3 1 2 2 03 1 2 2 13 1 210 1 1 le n le 10 5,1 le m le 2 times...

P3402 模板 可持久化並查集

其實看看 自己就可以懂。注意 1.並查集不壓縮路徑,壓縮了就回不到壓縮之前的狀態了。2.並查集合並時,小的往大的合併,啟發式合併。3.對於第i步 不管什麼操作 操作都要把root i roo i 1 我在合併時,如果兩個祖先一樣就直接continue了,沒把root i 賦值為root i 1 一直...

P3402 模板 可持久化並查集

今天看到這道題,忽然不知道為何要線段樹了 笑 出現了一些瞎搞的想法 然後就想到了操作樹。就是,我們可以離線,然後每個位置直接維護乙個棧,記錄歷史資訊。然鵝我也不知道為什麼常數很大 include define r register int using namespace std namespace ...