有三种操作,添加客户,输出优先级最高的客户并删掉,输出优先级最低的客户并删掉。作为学习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;
}