POJ 3481 Double Queue(Treap)

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;
}


 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值