POJ 3481 Double Queue(Treap)
http://poj.org/problem?id=3481
题意:
每个顾客有个编号和优先级,银行每次可以添加顾客的要求进队列,且保证队列中当前任意顾客的编号和优先级都不同.银行可以执行先服务最大优先级的顾客或者先服务最小优先级的顾客操作.对于每个服务,输出顾客的编号.
分析:
直接构建Treap,插入节点的v值(顾客优先级)和节点的r值(随机函数rand获得)以及节点信息info(顾客编号),然后对于每个操作,先find找到最大v值的节点信息info,然后在delete即可.
写find_min的时候复制了以下find_max的,结果复制错了.WA了以下,下次一定别复制.
AC代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
struct Node
{
Node *ch[2];
int r,v,info;//v是顾客优先级,info是顾客的编号,r由rand()生成
Node(int v,int info):v(v),info(info)
{
r=rand();
ch[0]=ch[1]=NULL;
}
int cmp(int x)
{
if(x==v) return -1;
return x<v? 0:1;
}
};
void rotate(Node* &o,int d)
{
Node *k=o->ch[d^1];
o->ch[d^1]=k->ch[d];
k->ch[d]=o;
o=k;
}
void insert(Node* &o,int v,int info)
{
if(o==NULL) o=new Node(v,info);
else
{
int d= v < o->v?0:1;
insert(o->ch[d],v,info);
if(o->ch[d]->r > o->r)
rotate(o,d^1);
}
}
void remove(Node *&o,int v)
{
int d=o->cmp(v);
if(d==-1)
{
Node *u=o;
if(o->ch[0] && o->ch[1])
{
int d2 = o->ch[0]->r < o->ch[1]->r ?0:1;
rotate(o,d2);
remove(o->ch[d2],v);
}
else
{
if(o->ch[0]==NULL)o=o->ch[1];
else o=o->ch[0];
delete u;
}
}
else remove(o->ch[d],v);
}
int find_max(Node *o)//找到最大v值
{
if(o->ch[1]==NULL)
{
printf("%d\n",o->info);
return o->v;
}
return find_max(o->ch[1]);
}
int find_min(Node *o)//找到最小v值
{
if(o->ch[0]==NULL)
{
printf("%d\n",o->info);
return o->v;
}
return find_min(o->ch[0]);
}
int main()
{
int op;
Node *root=NULL;
while(scanf("%d",&op)==1&&op)
{
if(op==1)
{
int info,v;
scanf("%d%d",&info,&v);
insert(root,v,info);
}
else if(op==2)
{
if(root==NULL){printf("0\n"); continue;}
int v=find_max(root);
remove(root,v);
}
else if(op==3)
{
if(root==NULL){printf("0\n"); continue;}
int v=find_min(root);
remove(root,v);
}
}
return 0;
}