2017 9 27 可持久化並查集 失敗總結

2021-08-08 19:31:25 字數 1422 閱讀 2696

這個題目就是誤導你的,據說zky用了rope。。所以苦於用並查集強行持久的似乎不太好做

這個題可以根據並查集的原理只加啟發式合併優化

這樣就可以常數巨大、空間巨大的nlogn了

啟發式合併的過程 對於數值上來說 就是乙個fu陣列賦值為另乙個的fu陣列,所以相當於單點修改

sz單點加

撤銷過程相當於回到前幾個詢問

很像主席樹啊,還是單點修改,,就比較好做了

注:1、複製貼上注意修改

2、注意查詢時用上一棵樹

3、注意開點的情況,,已經有了就不能再建了

碼:

#include#includeusing namespace std;

#define n 100005

int ch[(n<<2)*60][2],fu[(n<<2)*60],sz[(n<<2)*60],tot,op,a,b,c,cz,rt[n],n,m,i,j,x,y;

void jian(int o,int l,int r)

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

ch[o][0]=++tot;

ch[o][1]=++tot;

jian(ch[o][0],l,mid);

jian(ch[o][1],mid+1,r);

}void gai(int o,int l,int r,int last)

if(op==2)

if(op==3)

if(op==4)

return;

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

if(a<=mid)

else }

int main()

int c1=c;

c=y;

a=0;

while(a!=c)

int c2=c;

int cc1,cc2;

op=3;

a=c1;

gai(rt[i-1],1,n,rt[i-1]);

cc1=c;

a=c2;

gai(rt[i-1],1,n,rt[i-1]);

cc2=c;

if(cc1>cc2)swap(cc1,cc2);

op=1;

a=c1;

c=c2;

gai(rt[i],1,n,rt[i-1]);

op=2;

a=c2;

c=cc1;

gai(rt[i],1,n,rt[i-1]); }

if(cz==2)

if(cz==3)

int c1=c;

c=y;

a=0;

while(a!=c)

int c2=c;

if(c1==c2)

else printf("0\n");

} }

}

可持久化並查集

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