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

【分析】
本来写一个splay模板,想先过了这题然后去刷3580和维修数列的...
结果交上去果断T了,我大惊,莫非双旋比单旋还慢!
最后D了半天...发现是内存池的原因,知道真相的我眼泪掉下来.....话说我写内存池为什么就没成功过一次....
 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <assert.h>
#include <map>
#include <ctime>
#include <cstdlib> const int MAXN = + ;
const int INF = 0x7fffffff;
const int SIZE = ;
const int maxnode = + ;
using namespace std;
typedef int ll;
struct SPLAY{
struct Node{
int val, size;
int num;//num代表编号
Node *parent, *ch[]; Node(){
val = size = ;
num = ;
parent = ch[] = ch[] = NULL;
}
int cmp(){
if (parent == NULL) return -;
if (parent->ch[]->num == num) return ;
if (parent->ch[]->num == num) return ;
}
void update(){
size = ;
if (ch[] != NULL) size += ch[]->size;
if (ch[] != NULL) size += ch[]->size;
}
}*root, *nil, _nil, mem[];//我写内存池就没成功过 /*struct MEMPOOR{//内存池
queue< Node >Q;
Node mem[maxnode];
Node *nil; void init(Node *&t){
for (int i = 0; i < maxnode; i++) Q.push( mem[i] );
nil = t;
}
Node *get(){
Node *p = &(Q.front());
Q.pop();
p->parent = p->ch[0] = p->ch[1] = nil;
p->num = p->val = 0;
p->size = 1;
return p;
}
//回收内存
void push(Node *&p){
Q.push(*(p));
p->parent->ch[p->cmp()] = nil;
}
}poor;*/
int tot, cnt;//计数
/*void debug(){//测试内存池
poor.init();
Node *a = poor.get();
a->val = 10;
Node *b = poor.get();
b->val = 5;
a->ch[0] = b;
printf("%d\n", poor.Q.size());
printf("%d\n", a->val);
printf("%d\n", b->cmp());
}*/
Node *NEW(){
Node *p = &mem[cnt++];
p->parent = p->ch[] = p->ch[] = nil;
p->num = p->val = ;
p->size = ;
return p;
}
void init(){
//循环哨兵的定义
nil = &_nil;
_nil.parent = _nil.ch[] = _nil.ch[] = nil; tot = ;
cnt = ;
root = nil;
insert(root, -INF, -INF);
insert(root, INF, INF);
}
void rotate(Node *t, int d){
Node *p = t->parent;//t的右旋对于p来说也是右旋
t = p->ch[d ^ ];
p->ch[d ^ ] = t->ch[d];
t->ch[d]->parent = p;
t->ch[d] = p;
t->parent = p->parent;
//注意,这里要更新的原因在于t并不是引用
if (t->parent != nil){
if (t->parent->ch[] == p) t->parent->ch[] = t;
else if (t->parent->ch[] == p) t->parent->ch[] = t;
}
p->parent = t;
if (t->parent == nil) root = t;
//不用换回去了...
p->update();
t->update();
}
//将x旋转为y的子树
void splay(Node *x, Node *y){
while (x->parent != y){
if (x->parent->parent == y) rotate(x, (x->cmp() ^ ));
else{//不然连转两下
rotate(x->parent, x->parent->cmp() ^ );
rotate(x, x->cmp() ^ );
}
x->update();
}
}
//编号和权值
void insert(Node *&t, int num, int val){
if (t == nil){
t = NEW();
t->val = val;
t->num = num;
return;
}
Node *x = t;
while (){
int dir = (val > x->val);
if (x->ch[dir] == nil){
x->ch[dir] = NEW();
x->ch[dir]->val = val;
x->ch[dir]->num = num;
x->ch[dir]->parent = x;
splay(x->ch[dir], nil);
return;
}else x = x->ch[dir];
}
return;
}
void debug(){
/*init();
root = nil;
insert(root, 1, 1);
//printf("%d", root->val);
insert(root, 2, 2);
insert(root, 0, 0);
insert(root, 4, 4);
print(root);
//printf("%d\n", root->size); */
}
//找到val值为k的数的名次
int find(Node *t, int k){
if (t == nil) return -;//-1代表找不到
int tmp = t->ch[]->size;
if (k == t->val) return tmp + ;
else if (k < t->val) return find(t->ch[], k);
else return find(t->ch[], k) + tmp + ;
}
//找到第k小的权值并将其splay到根
void get(Node *t, Node *y, int k){
Node *x = t;
while (){
int tmp = x->ch[]->size;
if ((tmp + ) == k) break;
if (k <= tmp) x = x->ch[];
else {x = x->ch[]; k -= tmp + ;}
}
splay(x, y);
}
//删除val值为k的节点
void Delete(int k){
int tmp = find(root, k);
get(root, nil, tmp - );
get(root, root, tmp + );
//卡出来
//poor.push(root->ch[1]->ch[0]);
root->ch[]->ch[] = nil;
root->ch[]->update();
root->update();
return;
}
void print(Node *t){
if (t == nil) return;
print(t->ch[]);
printf("%d ", t->val);
print(t->ch[]);
} }A;
int n, m; void work(){
//A.root = nil;
A.init();//A.tot记录了A中的元素个数
int t;
while (scanf("%d", &t) && t){
if (t == ){
if (A.tot == ) {printf("0\n");continue;}
A.get(A.root, A.nil, A.tot + );
printf("%d\n", A.root->num);
A.Delete(A.root->val);
A.tot--;
}else if (t == ){
if (A.tot == ) {printf("0\n");continue;}
A.get(A.root, A.nil, );
printf("%d\n", A.root->num);
A.Delete(A.root->val);
A.tot--;
}else{
int val, num;
scanf("%d%d", &num, &val);
A.insert(A.root, num, val);
A.tot++;
}
}
} int main(){
#ifdef LOCAL
freopen("data.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
work();
//A.debug();
return ;
}

【POJ3481】【splay】Double Queue的更多相关文章

  1. BZOJ4012 [HNOI2015]开店 【动态点分治 + splay】

    题目链接 BZOJ4012 题解 Mychael并没有A掉,而是T掉了 讲讲主要思路 在点分树上每个点开两棵\(splay\), 平衡树\(A\)维护子树中各年龄到根的距离 平衡树\(B\)维护子树中 ...

  2. bzoj 3196 Tyvj 1730 二逼平衡树【线段树 套 splay】

    四舍五入就是个暴力. 对于线段树的每个区间都开一棵按权值排序的splay 对于第二个操作,二分一下,每次查询mid的排名,复杂度 $ O(nlog(n)^{3}) $ 其余的操作都是$ O(nlog( ...

  3. 【Map】Double Queue

    Double Queue Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13258   Accepted: 5974 Des ...

  4. 【BZOJ1492】【NOI2007】货币兑换(动态规划,CDQ分治,Splay)

    [BZOJ1492][NOI2007]货币兑换(动态规划,CDQ分治,Splay) 题面 BZOJ 洛谷 Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券 ...

  5. 【BZOJ1500】【NOI2005】维修数列(Splay)

    [BZOJ1500][NOI2005]维修数列(Splay) 题面 不想再看见这种毒瘤题,自己去BZOJ看 题解 Splay良心模板题 真的很简单 我一言不发 #include<iostream ...

  6. 【BZOJ1058】【ZJOI2007】报表统计(链表,堆,Splay)

    [BZOJ1058][ZJOI2007]报表统计 题面 题目描述 Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细观 ...

  7. 【hihocoder 1329】平衡树·Splay(Splay做法)

    [题目链接]:http://hihocoder.com/problemset/problem/1329 [题意] [题解] 插入操作:-,记住每次插入之后都要把它放到根节点去就好; 询问操作:对于询问 ...

  8. 【DataStructure】Description and usage of queue

    [Description] A queue is a collection that implements the first-in-first-out protocal. This means th ...

  9. 【洛谷】3960:列队【Splay】

    P3960 列队 题目描述 Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×m名学生,方阵的行数为  ...

  10. 【hihocoder 1329】 平衡树·Splay(set做法)

    [题目链接]:http://hihocoder.com/problemset/problem/1329 [题意] [题解] 因为一开始是空的树,所以; n其实就代表了树中的最多元素个数; 则最坏的情况 ...

随机推荐

  1. 转-----实现基本的Ajax和Json请求

    前面已经封装好了一个方法ajax(),通过这个方法可以实现Ajax请求,接下来就是给出 例程来测试这个方法和实现简单的功能.   视图的部分代码如下: 1 2 3 4 5 6 7 8 9 <bo ...

  2. LINUX系统中动态链接库的创建与使用{补充}

    大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library).这种动态链接库,和静态函数库不同,它里面的函数并不是执行程序本身的一部 ...

  3. JavaScript高级程序设计14.pdf

    继承,ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现的 构造函数.原型.和实例的关系:每个构造函数都有一个原型对象,每个原型对象都包含一个指向构造函数的指针,每个实例都包含一 ...

  4. 《算法问题实战策略》-chaper15-计算几何-线段相交

    这篇文章着力来讨论线段相交这一个问题. 给出两条线段,如何判断这两条线段相交? 如果这两条线段相交,如何求其交点? 线段相交问题通常由于其繁杂的情况种类而让人避而远之,在这里希望通过笔者的简化讨论希望 ...

  5. kickStart脚本

    kickstart是什么        许多系统管理员宁愿使用自动化的安装方法来安装红帽企业 Linux.为了满足这种需要,红帽创建了kickstart安装方法.使用kickstart,系统管理员可以 ...

  6. the partition number

    有一个容量为n的背包,有1, 2, 3, ..., n这n种物品,每种物品可以无限使用,求装满的方案数. 法一: http://mathworld.wolfram.com/PartitionFunct ...

  7. JS:九宫格抽奖转盘实例

    工作需要,所以做了个抽奖转盘的插件,当然这里只做最简单的演示.可以用于取代一些flash抽奖程序. 机制说明: 1.通过定义lottery-unit来控制节点的个数及索引: 2.通过设置lottery ...

  8. 手把手教你在ubuntu下创建桌面快捷方式

    习惯使用windows的朋友来说创建桌面快捷方式简直就是so easy, 鼠标右键点击文件-->选择发送桌面快捷方式.就OK了.对于ubuntu下该如何创建桌面快捷方式呢?以下以创建eclips ...

  9. 吧php脚本打包成 exe程序

    操作方法 :FQ哦 https://www.youtube.com/watch?v=UQ3zxqh1YXY 有很多方法可以实现 找了个外国的哥们制作的工具 可以吧文件生成很简单的一个独立EXE文件 下 ...

  10. android 37 线程通信Looper

    安卓程序的主线程也叫UI线程. 工作线程和主线程的差别:安卓主线程已经调用了Looper.prepare()方法了,已经有一个MessageQueue对象了,所以才可以在工作线程用Handler发消息 ...