题意:初始有n个空的栈,Q次操作.
操作1:将v压入第i个栈的栈顶.
操作2:弹出第i个栈的栈顶,并输出该栈顶的值.
操作3:将第t个栈的所有元素移到第s个栈的顶部. 移动后s变为:E(s,1)..E(s,S),E(t,1)..E(t,S)
n,Q<=3e5.v<=1e9 模拟以上操作.
设hd[i],ed[i]分别为第i个栈的开头和结尾的编号, sz[i]为第i个栈的大小.
val[id]为编号为id的数值. ls[id],nx[id] 表示id前面和后面的元素.
然后就是链表的基本操作,分别对以上三个操作模拟即可.(注意细节.....)
ps:也可以直接用list :: splice()
#include <bits/stdc++.h>
using namespace std;
const int N=6e5+5;
int n,Q,T,sz[N],id;
int val[N];//val[id] 编号为id的值
int nx[N],ls[N],hd[N],ed[N];//hd[s] 第s个栈的栈头编号. ed[s] s栈顶编号.
void init()
{
id=1;
for(int i=0;i<=max(n,Q)+5;i++)
sz[i]=nx[i]=ls[i]=val[i]=hd[i]=ed[i]=0;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&Q);
init();
int op,v,s,t;
while(Q--)
{
scanf("%d%d",&op,&s);
if(op==1)
{
++id;
scanf("%d",&v);
nx[ed[s]]=id,ls[id]=ed[s];
sz[s]++;
val[id]=v,ed[s]=id;
if(sz[s]==1)
hd[s]=id;
}
else if(op==2)
{
if(sz[s]>0)
{
printf("%d\n",val[ed[s]]);
ed[s]=ls[ed[s]];
sz[s]--;
if(sz[s]==0)
ed[s]=hd[s]=0;
}
else
puts("EMPTY");
}
else
{
scanf("%d",&t);
if(sz[t]>0)
{
if(sz[s]==0)
hd[s]=hd[t];
else
nx[ed[s]]=hd[t],ls[hd[t]]=ed[s];
ed[s]=ed[t];
sz[s]+=sz[t];
sz[t]=hd[t]=ed[t]=0;
}
}
}
}
return 0;
}