欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题意概括
有两个栈,有3种操作。 第一种是往其中一个栈加入一个数; 第二种是取出其中一个栈的顶端数字; 第三种是将其中一个栈的所有元素放入另外一个栈,元素顺序依旧按照加入顺序来放。
题解
写一下左偏树就可以了。
按照进入的时间为权值维护两个大根堆(栈先进后出)。
代码
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=100005;
int n,cnt,rt1,rt2;
int ls[N],rs[N],npl[N],val[N],time[N];
void makeheap(int x,int v,int t){
ls[x]=rs[x]=npl[x]=0;
val[x]=v,time[x]=t;
}
int merge(int a,int b){
if (!a||!b)
return a+b;
if (time[a]<time[b])
swap(a,b);
rs[a]=merge(rs[a],b);
if (npl[rs[a]]>npl[ls[a]])
swap(rs[a],ls[a]);
npl[a]=npl[rs[a]]+1;
return a;
}
void pop(int &rt){
rt=merge(ls[rt],rs[rt]);
}
int main(){
int Case=0;
while (~scanf("%d",&n)&&n){
printf("Case #%d:\n",++Case);
cnt=rt1=rt2=0;
while (n--){
char op[10],x1[3],x2[3];
int x;
scanf("%s",op);
if (op[0]=='m'){
scanf("%s%s",x1,x2);
if (x1[0]!='A')
swap(rt1,rt2);
rt1=merge(rt1,rt2);
rt2=0;
if (x1[0]!='A')
swap(rt1,rt2);
}
else if (op[1]=='o'){
scanf("%s",x1);
printf("%d\n",val[x1[0]=='A'?rt1:rt2]);
pop(x1[0]=='A'?rt1:rt2);
}
else {
scanf("%s%d",x1,&x);
cnt++;
makeheap(cnt,x,cnt);
if (x1[0]=='A')
rt1=merge(rt1,cnt);
else
rt2=merge(rt2,cnt);
}
}
}
return 0;
}