HDU5818 Joint Stacks 左偏树,可并堆

欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - HDU5818


题意概括

  有两个栈,有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;
}

  

原文地址:https://www.cnblogs.com/zhouzhendong/p/HDU5818.html