可撤销并查集
一定要按秩合并优化,不能路径压缩,不然不能保存父亲节点信息。复杂度:O(log(n))
struct dsu
{
int pre[N],top,sz[N];
p stk[N];
void init(int n)
{
for(int i=1; i<=n; i++)pre[i]=i,sz[i]=1;
top=0;
}
int find(int x)
{
if(x==pre[x])return x;
return find(pre[x]);
}
bool join(int u,int v)
{
u=find(u),v=find(v);
if(u==v)return 0;
if(sz[u]>sz[v])swap(u,v);
pre[u]=v;
sz[v]+=sz[u];
stk[top++]=MP(u,v);
return 1;
}
void cancel()
{
p now=stk[--top];
pre[now.first]=now.first;
sz[now.second]-=sz[now.first];
}
} dsu;