poj 3481 Double Queue

        有三种操作,添加客户,输出优先级最高的客户并删掉,输出优先级最低的客户并删掉。作为学习splay的题目,敲出了人生中的第一颗splay。居然和时限一样AC。

        小发现:因为写的是指针版的splay,后来加了一句free,把删除的节点free掉,运行快了不少。

#include <iostream>    
#include <stdio.h>    
#include <string>    
#include <map>    
#include <vector>    
#include <stack>    
#include <queue>    
#include <string.h>    
#include <algorithm>    
#include <math.h>    
    
using namespace std;    

struct node{
	node* pleft;
	node* pright;
	int pri;
	int id;
};

node* splay(node* pNode,int pri){
	if(pNode==NULL)return pNode;
	
	node* root=pNode;
	while(1){
		node* l=root->pleft;
		node* r=root->pright;
		if(pri<root->pri){
			if(l==NULL)break;
			if(pri<l->pri){
				root->pleft=l->pright;
				l->pright=root;
				root=l;
			}else{
				break;
			}
		}else{
			if(r==NULL)break;
			if(pri>r->pri){
				root->pright=r->pleft;
				r->pleft=root;
				root=r;
			}else{
				break;
			}
		}
	}
	return root;
}

node* insert(node* pNode,int id,int pri){
	//建立新节点 
	node* newNode=new node();
	newNode->id=id;
	newNode->pri=pri;
	//
	if(pNode!=NULL){
		pNode=splay(pNode,pri);
		if(pri<pNode->pri){
			newNode->pleft=pNode->pleft;
			newNode->pright=pNode;
			pNode->pleft=NULL;
		}else{
			newNode->pleft=pNode;
			newNode->pright=pNode->pright;
			pNode->pright=NULL;
		}
	}
	return newNode;
}

node* root;

int delMax(){
	if(root==NULL)return 0;
	node* t=root;
	node* del;
	while(t->pright){
		del=t;
		t=t->pright;
	}
	if(t==root){
		root=root->pleft;
	}else{
		del->pright=NULL;
	}
	int re=t->id;
	free(t);
	return re;
}

int delMin(){
	if(root==NULL)return 0;
	node* t=root;
	node* del;
	while(t->pleft){
		del=t;
		t=t->pleft;
	}
	if(t==root){
		root=root->pright;
	}else{
		del->pleft=NULL;
	}
	int re=t->id;
	free(t);
	return re;
}


int main(){
	int op;
	
	while(~scanf("%d",&op)){
		if(!op)break;
		if(op==1){
			int k,p;
			scanf("%d%d",&k,&p);
			root=insert(root,k,p);
		}else if(op==2){	//最高 
			int ans=delMax();
			printf("%d\n",ans);
		}else{				//最低 
			int ans=delMin();
			printf("%d\n",ans);
		}
	}
	return 0;
}


        为了学习Treap,又用Treap敲了一遍。。

#include <iostream>    
#include <stdio.h>    
#include <string>    
#include <map>    
#include <vector>    
#include <stack>    
#include <queue>    
#include <string.h>    
#include <algorithm>    
#include <math.h>    
    
using namespace std;    


struct treap{
	treap* pleft;
	treap* pright;
	int pri,id;
	int fix;		//修正值,小顶堆 
};


void LRotate(treap *&node){
	treap* r=node->pright;
	node->pright=r->pleft;
	r->pleft=node;
	node=r;
}

void RRotate(treap *&node){
	treap* l=node->pleft;
	node->pleft=l->pright;
	l->pright=node;
	node=l;
}

void insert(treap *&node,int id,int pri){
	if(node==NULL){
		treap* newNode=new treap();
		node=newNode;
		node->id=id;
		node->pri=pri;
		node->fix=rand();
	}else if(pri<node->pri){
		insert(node->pleft,id,pri);
		if(node->pleft->fix<node->fix){
			RRotate(node);
		}
	}else{
		insert(node->pright,id,pri);
		if(node->pright->fix<node->fix){
			LRotate(node);
		}
	}
	
}

int Minpri,Maxpri;

int findMin(treap* node){
	if(node==NULL)return 0;
	if(node->pleft)return findMin(node->pleft);
	Minpri=node->pri;
	return node->id;
}

int findMax(treap* node){
	if(node==NULL)return 0;
	if(node->pright)return findMax(node->pright);
	Maxpri=node->pri;
	return node->id;
}

void Delete(treap *&node,int val){
	if(node->pri==val){
		if(!node->pleft||!node->pright){
			treap* t=node;
			if(!node->pleft){
				node=node->pright;
			}else{
				node=node->pleft;
			}
			delete t;
		}else{	//两边都有 
			if(node->pleft->pri<node->pright->pri){
				RRotate(node);
				Delete(node->pright,val);
			}else{
				LRotate(node);
				Delete(node->pleft,val);
			}
		}
		
	}else if(val<node->pri){
		Delete(node->pleft,val);
	}else{
		Delete(node->pright,val);
	}
}


int main(){
	int op;
	treap* root=NULL;
    while(~scanf("%d",&op)){  
        if(!op)break;  
        if(op==1){  
            int k,p;  
            scanf("%d%d",&k,&p);  
            insert(root,k,p);  
        }else if(op==2){    //最高   
			int ans= findMax(root);
			printf("%d\n",ans);
			if(ans){
				Delete(root,Maxpri);
			}
        }else{              //最低   
        	int ans= findMin(root);
			printf("%d\n",ans);
			if(ans){
				Delete(root,Minpri);
			}
        }  
    }
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值