zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    习题三 答案
    习题二 答案
    Python开发【第三篇】:Python基本数据类型
    习题四 答案
    第一个python程序-判断登陆用户名和密码是否正确
    BFPRT算法 查找第k小的数
    设计模式----单例模式
    设计模式----原型模式
    非本地跳转
    链接器如何使用静态库解析引用
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/HDU5818.html
Copyright © 2011-2022 走看看