可持久化並查集

2022-08-18 22:51:14 字數 1570 閱讀 6690

可持久化資料結構是在原資料結構的基礎上增加維護歷史版本的功能。但可持久化並查集的具體思路是利用主席樹維護不同版本的每個節點的父節點.如果並查集結構是鏈式,用按秩合併會導致單次查詢複雜度為\(n\log n\),於是我們可以啟發式合併,將最大深度較小的集合合併到較大的那乙個.剩下的,暴力查詢暴力合併即可.由於我不想(會)打啟發式合併,於是寫了手隨機化,平均複雜度o(nlog^n),可以通過所有資料.

#include#include#include#include#include#include#include#include#include#include#include#define r register

#define next kdjadskfj

#define debug puts("mlg")

#define mod 31011

#define mod(x) ((x%mod+mod)%mod)

using namespace std;

typedef long long ll;

typedef long double ld;

typedef unsigned long long ull;

template inline void read(t &x);

template inline void write(t x);

template inline void writesp(t x);

template inline void writeln(t x);

const ll n=1e5+5, m=2e5+5;

ll n, m;

ll rt[m];

namespace seg

inline ll getf(ll p, ll l, ll r, ll k, ll &d, ll ffa)

ll mid=l+r>>1;

if(k<=mid) return getf(lc[p], l, mid, k, d, ffa);

else return getf(rc[p], mid+1, r, k, d, ffa); }

inline void update(ll &p, ll fa, ll l, ll r, ll k, ll ffa)

inline ll get(ll p, ll l, ll r, ll k)

inline void merge(ll k, ll x, ll y)

inline void check(ll k,ll x,ll y)

}ll nouse;

int main()

else

else

} }}template inline void read(t &x)

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

x*=t;

}template inline void write(t x)

if(x<=9)

write(x/10); putchar(x%10+'0');

}template inline void writesp(t x)

template inline void writeln(t x)

可持久化並查集

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 ...

可持久化並查集

點此看題 並查集最重要的就是fafa fa陣列,我們可以拿主席樹來維護這個fafa fa,並且每次改點只需要改乙個,為保證時間複雜度我們再維護乙個dep depde p來做啟發式合併,這就變成了乙個單點修改,單點查詢的主席樹了。include include using namespace std ...