#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int res=0,flag=1;
char ch=getchar();
while(!isalnum(ch)) (ch=='-')?flag=-1:1,ch=getchar();
while(isalnum(ch)) res=res*10+ch-'0',ch=getchar();
return res*flag;
}
inline void write(int x)
{
char buf[20]; int len=0;
if(x<=0) putchar((x==0)?'0':'-'); x=abs(x);
while(x!=0) buf[++len]=x%10+'0',x/=10;
while(len!=0) putchar(buf[len--]);
putchar('\n');
return ;
}
struct edge
{
int to,nxt;
};
struct node
{
short opt;
int x,y;
};
struct edge ed[100010];
struct node nd[100010];
int n,m,tot,len,sum;
int val[100010];
int id[100010],fa[100010];
int head[200010];
int ans[100010];
unsigned short size[100010];
unsigned short data[100010][41];
void init()
{
n=read(),m=read();
len=2500,sum=ceil((double)(n/len));
for(int i=1;i<=n;i++)
val[i]=read(),fa[i]=id[i]=i;
sort(id+1,id+n+1,[](int a,int b)->bool{return val[a]<val[b];});
for(int i=1,cnt=1;i<=n;i++)
{
size[i]=data[id[i]][cnt]=1;
if(i%len==0)
cnt++;
}
return ;
}
void add_edge(int fr,int to)
{
ed[++tot]=(edge){to,head[fr]};
head[fr]=tot;
return ;
}
int find(int x)
{
if(fa[x]==x)
return x;
return find(fa[x]);
}
void add(int &x,int &y)
{
x=find(x),y=find(y);
if(x==y) return ;
if(size[x]<size[y])
swap(x,y);
fa[y]=x;
size[x]+=size[y];
for(int i=1;i<=sum;i++)
data[x][i]+=data[y][i];
return ;
}
void del(int x,int y)
{
if(x==y) return ;
fa[y]=y;
size[x]-=size[y];
for(int i=1;i<=sum;i++)
data[x][i]-=data[y][i];
return ;
}
int query(int pos,int k)
{
pos=find(pos);
if(size[pos]<k)
return -1;
for(int i=1;i<=sum;i++)
{
if(k-data[pos][i]>0)
{
k-=data[pos][i];
continue;
}
for(int j=len*(i-1)+1;j<=len*i+1;j++)
{
if(find(id[j])==pos) k--;
if(k==0) return val[id[j]];
}
}
return -1;
}
void dfs(int fr)
{
if(nd[fr].opt==1)
add(nd[fr].x,nd[fr].y);
if(nd[fr].opt==3)
ans[fr]=query(nd[fr].x,nd[fr].y);
for(int i=head[fr];i!=0;i=ed[i].nxt)
dfs(ed[i].to);
if(nd[fr].opt==1)
del(nd[fr].x,nd[fr].y);
return ;
}
int main(int argc,const char *argv[])
{
init();
for(int i=1;i<=m;i++)
{
nd[i].opt=read();
if(nd[i].opt==2)
{
nd[i].x=read();
add_edge(nd[i].x,i);
continue;
}
nd[i].x=read();
nd[i].y=read();
add_edge(i-1,i);
}
dfs(0);
for(int i=1;i<=m;i++)
if(nd[i].opt==3)
write(ans[i]);
return 0;
}
同一份代码,前几天能 AC,今天测不管是本地 or 洛谷 IDE or 隔壁 @xhgua 的机子都过不了样例但是还是能 A???