测试题目
洛谷模板题传送门
Code:
//By zuiyumeng
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Re register
#define Ms(a,b) memset((a),(b),sizeof(a))
#define Fo(i,a,b) for(Re int i=(a),_=(b);i<=_;i++)
#define Ro(i,a,b) for(Re int i=(b),_=(a);i>=_;i--)
using namespace std;
inline int read() {
int x=0,f=1;char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
return x*f;
}
const int N=100010;
int n,m,cnt;
int fa[N*20],root[N*20],ls[N*20],rs[N*20],dep[N*20];
#define mid ((l+r)>>1)
void build(int &cur,int l,int r) {
cur=++cnt;
if(l==r) {fa[cur]=l;return ;}
build(ls[cur],l,mid); build(rs[cur],mid+1,r);
}
void merge(int las,int &cur,int l,int r,int u,int v) {
cur=++cnt; ls[cur]=ls[las]; rs[cur]=rs[las];
if(l==r) fa[cur]=v,dep[cur]=dep[las];
else if(u<=mid) merge(ls[las],ls[cur],l,mid,u,v); //注意las和cur跟着一起跳
else merge(rs[las],rs[cur],mid+1,r,u,v);
}
void update(int cur,int l,int r,int u) {
if(l==r) dep[cur]++;
else if(u<=mid) update(ls[cur],l,mid,u);
else update(rs[cur],mid+1,r,u);
}
int getnm(int cur,int l,int r,int u) {
if(l==r) return cur;
else if(u<=mid) return getnm(ls[cur],l,mid,u);
else return getnm(rs[cur],mid+1,r,u);
}
int getro(int rt,int u) {
int num=getnm(rt,1,n,u);
return fa[num]==u?num:getro(rt,fa[num]); //注意这里返回的是num,因为对应值可以由fa[num]得到
}
int main() {
n=read(); m=read();
build(root[0],1,n);
Fo(i,1,m) {
int opt=read();
if(opt==1) {
int u=read(),v=read();
int ru=getro(root[i-1],u),rv=getro(root[i-1],v);
if(dep[ru]>dep[rv]) swap(ru,rv);
merge(root[i-1],root[i],1,n,fa[ru],fa[rv]);
if(dep[ru]==dep[rv]) update(root[i],1,n,fa[rv]);
}
else if(opt==2) root[i]=root[read()];
else {
int u=read(),v=read();
root[i]=root[i-1];
int ru=getro(root[i],u),rv=getro(root[i],v);
if(ru==rv) cout<<1<<endl;
else cout<<0<<endl;
}
}
return 0;
}