Description
n Sets of M operations
Operation:
1 A B merges the set of A and a
2 k back to status after K-operation (query counts as action)
3 A B asks if a, a, or not belongs to the same set, is output 1 otherwise output 0
0<n,m<=2*10^4
Inputoutputsample Input
5 6 1 1 2 3 1 2 2 0 3 1 2 2 1 3 1 2
Sample Output
1 0 1
Solution
Use rope to implement a persistent array, using the rope history function to achieve persistence and search, through time 168ms
#include <cstdio>#include<ext/rope>#include<iostream>using namespacestd;using namespace__gnu_cxx;inlineintRin () {intx=0, C=getchar (), f=1; for(;c< -|| C> $; c=GetChar ())if(! (c^ $)) f=-1; for(;c> -&&c< -; c=GetChar ()) x= (x<<1) + (x<<3) +c- -; returnx*F;}Const intm=20010; Rope<int>*His[m];intN,m,a[m];inlineintFindintIintx) { intD=x,p; while(His[i]->at (x) ^x) x=his[i]->At (x); while(d^x) P=his[i]->at (d), His[i]->replace (d,x), d=p; returnx;} InlinevoidMergeintIintXinty) {x=find (i,x), y=find (I,y); if(x^y) his[i]-replace (y,x);}intMain () {n=rin (), m=Rin (); for(intI=1; i<=n;i++) a[i]=i; his[0]=Newrope<int> (a,a+1+N); for(intI=1, x,y,sign;i<=m;i++) {His[i]=Newrope<int> (*his[i-1]); scanf ("%d",&Sign ); Switch(sign) { Case 1: x=rin (), y=Rin (); Merge (I,x,y); Break; Case 2: x=Rin (); His[i]=His[x]; Break; Case 3: x=rin (), y=Rin (); printf ("%d\n",(! (Find (i,x) ^find (I,y))); Break; } } return 0;}
[bzoj3673] [can be persisted and checked by Zky] (Rope (persistent array) + and check set = can be persisted and looked up)