欢迎访问~原文出处——博客园-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: ",++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 ",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; }