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

【分析】
本来写一个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. (转载)javascript客户端生成MD5值的函数代码

    (转载)http://www.jb51.net/article/26223.htm 用js实现的客户端即可实现md5值的代码,一般情况下都是后台语言才有的,客户端也有了,方便有需要的朋友了. 测试代码 ...

  2. Delphi WebService 需要注意 转

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://gang4415.blog.51cto.com/225775/251997 Web ...

  3. 导入 from pdfminer.pdfinterp import process_pdf 错误

    >>> from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter>>> from ...

  4. AOP Aspect Oriented Programming

    原理AOP(Aspect Oriented Programming),也就是面向方面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP将应用系统分为两部分,核心业务逻辑(Core bus ...

  5. scanf从文件中读入,printf写入到文件

    重定向方式读写文件 #include <stdio.h> #define LOCAL int main() { #ifdef LOCAL freopen("input.txt&q ...

  6. grunt个人理解

    最近在学习grunt的内容,也希望能将grunt使用在新的项目中,本文是对grunt的相关概念的个人理解,仅供与道友们交流和学习,如有疑义,欢迎道友们指点. 首先,grunt是基于nodejs的,那就 ...

  7. 【设计模式 - 1】之工厂模式(Factory)

    1      模式简介 1.1    工厂模式作用 工厂模式解决的是"使用new关键字获取对象造成松耦合"的问题. 工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏 ...

  8. Android中RelativeLayout的字符水平(垂直居中)对齐

    [背景] 此处Android中显示出来的TextView中的内容,水平中间不对其. 想要实现水平居中对齐. [折腾过程] 1.搜: android RelativeLayout horizontal ...

  9. Delphi ListView基本用法大全

    //增加项或列(字段) ListView1.Clear; ListView1.Columns.Clear; ListView1.Columns.Add; ListView1.Columns.Add; ...

  10. dump_stack的简单使用 +CALL TREE

    http://blog.chinaunix.net/uid-26403844-id-3361770.html http://blog.csdn.net/zifeng274059226/article/ ...