POJ-3481 Double Queue

Double Queue
题目链接
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 18268 Accepted: 7859
Description

The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing environment provided by IBM Romania, and using modern information technologies. As usual, each client of the bank is identified by a positive integer K and, upon arriving to the bank for some services, he or she receives a positive integer priority P. One of the inventions of the young managers of the bank shocked the software engineer of the serving system. They proposed to break the tradition by sometimes calling the serving desk with the lowest priority instead of that with the highest priority. Thus, the system will receive the following types of request:

0 The system needs to stop serving
1 K P Add client K to the waiting list with priority P
2 Serve the client with the highest priority and drop him or her from the waiting list
3 Serve the client with the lowest priority and drop him or her from the waiting list
Your task is to help the software engineer of the bank by writing a program to implement the requested serving policy.

Input

Each line of the input contains one of the possible requests; only the last line contains the stop-request (code 0). You may assume that when there is a request to include a new client in the list (code 1), there is no other request in the list of the same client or with the same priority. An identifier K is always less than 106, and a priority P is less than 107. The client may arrive for being served multiple times, and each time may obtain a different priority.

Output

For each request with code 2 or 3, the program has to print, in a separate line of the standard output, the identifier of the served client. If the request arrives when the waiting list is empty, then the program prints zero (0) to the output.

Sample Input

2
1 20 14
1 30 3
2
1 10 99
3
2
2
0
Sample Output

0
20
30
10
0
Source

题目大意
有 4 种:
0 停止操作
1 加入一个编号为k,优先级为p的人
2 输出当期优先级最高的人的编号并删除这个人
3 输出当期优先级最低的人的编号并删除这个人
时间:1s
空间:64MB

题解
很明显可以用平衡树来维护。(我写了Treap)

也可以用两个堆(一个大根一个小根)来维护,vis数组表示编号为k的人是否在队列里。
1 操作相当于修正vis,再往两个堆里都推入这个元素。
2 操作删除第一个满足在队列里的堆顶(不在就删掉)
3 操作同理。
由于没有明确操作次数,如果只有 0、1 和 2 操作,那么很可能小根堆会炸掉。
不过也不用太担心,因为时限是 1 秒,我们开到 10^6 就肯定够了(如果操作次数>10^6,n*log(n)可能要超时)

代码
Treap

#include<ctime>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e6+5;
int n,k,p;
struct nod{
    nod *s[2];
    int k,p,r;
    nod(int k1,int p1,int r1){s[0]=s[1]=NULL;k=k1;p=p1;r=r1;}
}*rot;
int read()
{
    int ret=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
    return ret*f;
}
int rd(){return rand()<<16|rand()<<1|(rand()&1);}
void rotate(nod* &x,int p)//把x转动到x的p儿子的位置 
{
    nod *y=x->s[p^1];
    if (y==NULL) return;
    x->s[p^1]=y->s[p];
    y->s[p]=x;
    x=y;
    int c=1+1;
}
void insert(nod* &x,int k,int p)
{
    if (x==NULL) {x=new nod(k,p,rd());return;}
    int d=p>x->p;
    insert(x->s[d],k,p);
    if (x->s[d]->r>x->r) rotate(x,d^1);
}
void del(nod* &x)
{
    if (x->s[0]==NULL) x=x->s[1];else
    if (x->s[1]==NULL) x=x->s[0];else
    {
        int d=(x->s[0]->r>x->s[1]->r)?1:0;
        rotate(x,d);del(x->s[d]);
    }
}
bool fin(nod* &x,int f)//z=0表示最小,z=1表示最大 
{
    if (x==NULL) return 1;
    if (fin(x->s[f],f)) {printf("%d\n",x->k);del(x);return 0;}
    return 0;
}
int main()
{
    srand((unsigned int)(time(NULL)));
    while (n=read())
      if (n==1) {k=read();p=read();insert(rot,k,p);}else if (fin(rot,n==2)) printf("0\n");
    return 0;
}

#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=1e6+6;
struct js{
    int k,p;
    bool operator <(const js b)const{return p<b.p;}
    bool operator >(const js b)const{return p>b.p;}
}h[2][maxn];
int n,tot[2],k,p;
bool vis[maxn];
int put(int o,int k,int p)
{
    h[o][++tot[o]]=(js){k,p};
    if (o) push_heap(h[o]+1,h[o]+tot[o]+1);
      else push_heap(h[o]+1,h[o]+tot[o]+1,greater<js>());
}
int get(int o)
{
    if (o) pop_heap(h[o]+1,h[o]+tot[o]+1);
      else pop_heap(h[o]+1,h[o]+tot[o]+1,greater<js>());
    return h[o][tot[o]--].k;
}
int main()
{
    while (1)
    {
        scanf("%d",&n);
        if (n==0) break;
        if (n==1)
        {
            scanf("%d%d",&k,&p);
            vis[k]=0;
            put(0,k,p);put(1,k,p);
        }else if (n==2)
        {
            while (tot[1]>0&&vis[h[1][1].k]) get(1);
            if (tot[1]>0) vis[h[1][1].k]=1,printf("%d\n",get(1));
            else printf("0\n");
        }else
        {
            while (tot[0]>0&&vis[h[0][1].k]) get(0);
            if (tot[0]>0) vis[h[0][1].k]=1,printf("%d\n",get(0));
            else printf("0\n");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xu0_zy/article/details/80338577