1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| namespace lly { constexpr int N=1e5+5,B=1300,BB=1305; namespace dsu { int fa[N],siz[N],rsiz[N]; inline void init(int n){for(int i=1;i<=n;i++)fa[i]=i,siz[i]=1,rsiz[i]=0;} inline int find(int x){while(fa[x]!=x)x=fa[x];return x;} struct dat{int x,y;}stk[N];int top=0; inline void merge(int x,int y) { if(siz[x]<siz[y])swap(x,y); stk[++top]=(dat){x,y}; if(x==y)return; siz[x]+=siz[y];rsiz[x]+=rsiz[y];fa[y]=x; } inline void undo() { int x=stk[top].x,y=stk[top].y;top--; if(x==y)return; fa[y]=y;siz[x]-=siz[y];rsiz[x]-=rsiz[y]; } } int n,m; struct edge{int to,nxt;}e[N<<1]; int head[N],cnt=0; inline void add(int u,int v) { e[++cnt]=(edge){v,head[u]}; head[u]=cnt; } int a[N],ord[N],b[N],bel[N],L[N],R[N],bsiz,dfn[N<<1],ans[N],idx=0; struct Q{int op,x,y;}q[N]; inline void dfs(int u) { if(u) { dfn[++idx]=u; if(q[u].op==1) { int x=dsu::find(q[u].x),y=dsu::find(q[u].y); q[u]=(Q){1,x,y};dsu::merge(x,y); } else q[u].x=dsu::find(q[u].x); } for(int i=head[u];i;i=e[i].nxt){int v=e[i].to;dfs(v);} if(u){dfn[++idx]=-u;if(q[u].op==1)dsu::undo();} } int pre[N]; inline void work() { using IO::qread;using IO::qwrite;using IO::pc; qread(n),qread(m); for(int i=1;i<=n;i++)qread(a[i]),ord[i]=i; sort(ord+1,ord+n+1,[](const int x,const int y)->bool{return a[x]<a[y]||(a[x]==a[y]&&x<y);}); for(int i=1;i<=n;i++)b[ord[i]]=i; for(int i=1;i<=n;i++)bel[i]=(i-1)/B+1,R[bel[i]]=i,L[bel[i]]=(L[bel[i]]?L[bel[i]]:i); bsiz=bel[n]; int now=0; for(int i=1;i<=m;i++) { int op,x,y;qread(op),qread(x); if(op==2){if(!q[x].op)pre[i]=pre[x];else pre[i]=x;now=pre[i];continue;} qread(y),add(now,i),now=i,q[i]=(Q){op,x,y}; } dsu::init(n); dfs(0); for(int i=1;i<=bsiz;i++) { dsu::init(n); for(int j=1;j<=n;j++) if(L[i]<=b[j]&&b[j]<=R[i]) dsu::rsiz[j]=1; for(int j=1;j<=idx;j++) { if(dfn[j]>0) { int u=dfn[j]; if(q[u].op==1) dsu::merge(q[u].x,q[u].y); else if(q[u].op==3) { if(q[u].y) { int w=dsu::rsiz[q[u].x]; if(q[u].y>w) q[u].y-=w; else for(int k=L[i];k<=R[i];k++) { if(dsu::find(ord[k])==q[u].x) q[u].y--; if(!q[u].y){ans[u]=ord[k];break;} } } } } else{int u=-dfn[j];if(q[u].op==1)dsu::undo();} } } for(int i=1;i<=m;i++) if(q[i].op==3) qwrite(ans[i]?a[ans[i]]:-1),pc('\n'); } }
CPP
|