【POJ3481】【splay】Double Queue

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

Southeastern Europe 2007

【分析】

本来写一个splay模板,想先过了这题然后去刷3580和维修数列的...

结果交上去果断T了,我大惊,莫非双旋比单旋还慢!

最后D了半天...发现是内存池的原因,知道真相的我眼泪掉下来.....话说我写内存池为什么就没成功过一次....

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <vector>
  6 #include <utility>
  7 #include <iomanip>
  8 #include <string>
  9 #include <cmath>
 10 #include <queue>
 11 #include <assert.h>
 12 #include <map>
 13 #include <ctime>
 14 #include <cstdlib>
 15
 16 const int MAXN = 100001 + 10;
 17 const int INF = 0x7fffffff;
 18 const int SIZE = 450;
 19 const int maxnode =  10000000 + 10;
 20 using namespace std;
 21 typedef int ll;
 22 struct SPLAY{
 23        struct Node{
 24               int val, size;
 25               int num;//num代表编号
 26               Node *parent, *ch[2];
 27
 28               Node(){
 29                      val = size = 0;
 30                      num = 0;
 31                      parent = ch[0] = ch[1] = NULL;
 32               }
 33               int cmp(){
 34                   if (parent == NULL) return -1;
 35                   if (parent->ch[0]->num == num) return 0;
 36                   if (parent->ch[1]->num == num) return 1;
 37               }
 38               void update(){
 39                    size = 1;
 40                    if (ch[0] != NULL) size += ch[0]->size;
 41                    if (ch[1] != NULL) size += ch[1]->size;
 42               }
 43        }*root, *nil, _nil, mem[1222222];//我写内存池就没成功过
 44
 45        /*struct MEMPOOR{//内存池
 46               queue< Node >Q;
 47               Node mem[maxnode];
 48               Node *nil;
 49
 50               void init(Node *&t){
 51                    for (int i = 0; i < maxnode; i++) Q.push( mem[i] );
 52                    nil = t;
 53               }
 54               Node *get(){
 55                    Node *p = &(Q.front());
 56                    Q.pop();
 57                    p->parent = p->ch[0] = p->ch[1] = nil;
 58                    p->num = p->val = 0;
 59                    p->size = 1;
 60                    return p;
 61               }
 62               //回收内存
 63               void push(Node *&p){
 64                    Q.push(*(p));
 65                    p->parent->ch[p->cmp()] = nil;
 66               }
 67        }poor;*/
 68        int tot, cnt;//计数
 69        /*void debug(){//测试内存池
 70             poor.init();
 71             Node *a = poor.get();
 72             a->val = 10;
 73             Node *b = poor.get();
 74             b->val = 5;
 75             a->ch[0] = b;
 76             printf("%d\n", poor.Q.size());
 77             printf("%d\n", a->val);
 78             printf("%d\n", b->cmp());
 79        }*/
 80        Node *NEW(){
 81             Node *p = &mem[cnt++];
 82             p->parent = p->ch[0] = p->ch[1] = nil;
 83             p->num = p->val = 0;
 84             p->size = 1;
 85             return p;
 86        }
 87        void init(){
 88             //循环哨兵的定义
 89             nil = &_nil;
 90             _nil.parent = _nil.ch[0] = _nil.ch[1] = nil;
 91
 92             tot = 0;
 93             cnt = 0;
 94             root = nil;
 95             insert(root, -INF, -INF);
 96             insert(root, INF, INF);
 97        }
 98        void rotate(Node *t, int d){
 99             Node *p = t->parent;//t的右旋对于p来说也是右旋
100             t = p->ch[d ^ 1];
101             p->ch[d ^ 1] = t->ch[d];
102             t->ch[d]->parent = p;
103             t->ch[d] = p;
104             t->parent = p->parent;
105             //注意,这里要更新的原因在于t并不是引用
106             if (t->parent != nil){
107                if (t->parent->ch[0] == p) t->parent->ch[0] = t;
108                else if (t->parent->ch[1] == p)  t->parent->ch[1] = t;
109             }
110             p->parent = t;
111             if (t->parent == nil) root = t;
112             //不用换回去了...
113             p->update();
114             t->update();
115        }
116        //将x旋转为y的子树
117        void splay(Node *x, Node *y){
118             while (x->parent != y){
119                   if (x->parent->parent == y) rotate(x, (x->cmp() ^ 1));
120                   else{//不然连转两下
121                        rotate(x->parent, x->parent->cmp() ^ 1);
122                        rotate(x, x->cmp() ^ 1);
123                   }
124                   x->update();
125             }
126        }
127        //编号和权值
128        void insert(Node *&t, int num, int val){
129             if (t == nil){
130                t = NEW();
131                t->val = val;
132                t->num = num;
133                return;
134             }
135             Node *x = t;
136             while (1){
137                   int dir = (val > x->val);
138                   if (x->ch[dir] == nil){
139                      x->ch[dir] = NEW();
140                      x->ch[dir]->val = val;
141                      x->ch[dir]->num = num;
142                      x->ch[dir]->parent = x;
143                      splay(x->ch[dir], nil);
144                      return;
145                   }else x = x->ch[dir];
146             }
147             return;
148        }
149        void debug(){
150             /*init();
151             root = nil;
152             insert(root, 1, 1);
153             //printf("%d", root->val);
154             insert(root, 2, 2);
155             insert(root, 0, 0);
156             insert(root, 4, 4);
157             print(root);
158             //printf("%d\n", root->size); */
159        }
160        //找到val值为k的数的名次
161        int find(Node *t, int k){
162            if (t == nil) return -1;//-1代表找不到
163            int tmp = t->ch[0]->size;
164            if (k == t->val) return tmp + 1;
165            else if (k < t->val) return find(t->ch[0], k);
166            else return find(t->ch[1], k) + tmp + 1;
167        }
168        //找到第k小的权值并将其splay到根
169        void get(Node *t, Node *y, int k){
170            Node *x = t;
171            while (1){
172                  int tmp = x->ch[0]->size;
173                  if ((tmp + 1) == k) break;
174                  if (k <= tmp) x = x->ch[0];
175                  else {x = x->ch[1]; k -= tmp + 1;}
176            }
177            splay(x, y);
178        }
179        //删除val值为k的节点
180        void Delete(int k){
181             int tmp = find(root, k);
182             get(root, nil, tmp - 1);
183             get(root, root, tmp + 1);
184             //卡出来
185             //poor.push(root->ch[1]->ch[0]);
186             root->ch[1]->ch[0] = nil;
187             root->ch[1]->update();
188             root->update();
189             return;
190        }
191        void print(Node *t){
192             if (t == nil) return;
193             print(t->ch[0]);
194             printf("%d ", t->val);
195             print(t->ch[1]);
196        }
197
198 }A;
199 int n, m;
200
201
202 void work(){
203      //A.root = nil;
204      A.init();//A.tot记录了A中的元素个数
205      int t;
206      while (scanf("%d", &t) && t){
207             if (t == 2){
208                if (A.tot == 0) {printf("0\n");continue;}
209                A.get(A.root, A.nil, A.tot + 1);
210                printf("%d\n", A.root->num);
211                A.Delete(A.root->val);
212                A.tot--;
213             }else if (t == 3){
214                if (A.tot == 0) {printf("0\n");continue;}
215                A.get(A.root, A.nil, 2);
216                printf("%d\n", A.root->num);
217                A.Delete(A.root->val);
218                A.tot--;
219             }else{
220                   int val, num;
221                   scanf("%d%d", &num, &val);
222                   A.insert(A.root, num, val);
223                   A.tot++;
224             }
225      }
226 }
227
228
229 int main(){
230     #ifdef LOCAL
231     freopen("data.txt", "r", stdin);
232     freopen("out.txt", "w", stdout);
233     #endif
234     work();
235     //A.debug();
236     return 0;
237 }

时间: 2024-10-11 17:58:36

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

3196. 二逼平衡树【线段树套splay】

Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在区间内的前驱(前驱定义为小于x,且最大的数) 5.查询k在区间内的后继(后继定义为大于x,且最小的数) Input 第一行两个数 n,m 表示长度为n的有序序列和m个操作 第二行有n个数,表示有序序列 下面有m行,opt表示操作标号 若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间

【Map】Double Queue

Double Queue Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13258   Accepted: 5974 Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing environment provid

【UOJ】【UR #2】猪猪侠再战括号序列(splay/贪心)

http://uoj.ac/problem/31 纪念伟大的没有调出来的splay... 竟然那个find那里写错了!!!!!!!!!!!!! 以后要记住:一定要好好想过! (正解的话我就不写了,太简单了.. #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> #

【DataStructure】Description and usage of queue

[Description] A queue is a collection that implements the first-in-first-out protocal. This means that the only accessiable object in the collection in the first one that was inserted. The most common example of a queue is a waiting line. [Interface]

【BZOJ】【3007】拯救小云公主

思路题 我的naive的做法是二分答案+判定是否有路径可走……但是没有正确理解[走的方向任意]这句话…… 其实就是说想咋走咋走= =360°无死角乱走…… 所以其实是个平面上的问题…… 我们可以换个方向来考虑……二分一个答案,判断英雄走到/走不到公主那里,是不是就等价于,boss控制的区域连起来了使得英雄走不到公主那里了?(狼抓兔子的即视感) 所以我们可以转化成从上边&左边,在boss之间走,使得走到下边&右边 路径上最大的一条边(边权代表着如果英雄从这两个boss之间经过,离两个boss

【BZOJ】【1415】【NOI2005】聪聪和可可

数学期望+记忆化搜索 论文:<浅析竞赛中一类数学期望问题的解决方法>——汤可因  中的第一题…… Orz 黄学长 我实在是太弱,这么简单都yy不出来…… 宽搜预处理有点spfa的感觉= =凡是更新了的,都要重新入队更新一遍…… dp的记忆化搜索过程好厉害…… 期望这里一直很虚啊,赶紧再多做点题熟悉熟悉…… 1 /************************************************************** 2 Problem: 1415 3 User: Tunix

【CodeM初赛B轮】F 期望DP

[CodeM初赛B轮]F 题目大意:有n个景点,m条无向边,经过每条边的时间需要的时间是l,在每个景点游览花费的时间是t,游览完每个景点可以获得的满意度是h.你的总时间为k,起初你等概率的选择游览一个景点,然后每次等概率的前往一个相邻的景点游览,当你剩余时间不够游览一个相邻的景点时就结束游览.问所获得的满意度的期望值.(本题强行询问两次~) n<=100,总时间<=500 题解:显然的期望DP啊,不过本题的细节比较多,我这里只说一些细节吧~ 用f[i][j]表示游览完景点i,还剩时间j,所获得

【USACO 1.5.2】特殊的质数肋骨

[题目描述]农民约翰的母牛总是生产出最好的肋骨.你能通过农民约翰和美国农业部标记在每根肋骨上的数字认出它们. 农民约翰确定他卖给买方的是真正的质数肋骨,是因为从右边开始切下肋骨,每次还剩下的肋骨上的数字都组成一个质数,举例来说:  7 3 3 1全部肋骨上的数字 7331是质数;三根肋骨 733是质数;二根肋骨 73 是质数;当然,最后一根肋骨 7 也是质数. 7331 被叫做长度 4 的特殊质数. 写一个程序对给定的肋骨的数目 N (1<=N<=8),求出所有的特殊质数.数字1不被看作一个质

【USACO 1.5.1】回文质数

[题目描述] 因为151既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数. 写一个程序来找出范围[a,b](5 <= a < b <= 100,000,000)( 一亿)间的所有回文质数; [格式] INPUT FORMAT: (file pprime.in) 第 1 行: 二个整数 a 和 b . OUTPUT FORMAT: (file pprime.out) 输出一个回文质数的列表,一行一个. [分析] 晕,交了3遍才过.(不要鄙视我了==) 先

【BZOJ3527】【FFT】力

[问题描述]给出n个数qi,给出Fj的定义如下:令Ei=Fi/qi.试求Ei.[输入格式]输入文件force.in包含一个整数n,接下来n行每行输入一个数,第i行表示qi.[输出格式]输出文件force.out有n行,第i行输出Ei.与标准答案误差不超过1e-2即可.[样例输入]54006373.88518415375036.4357591717456.4691448514941.0049121410681.345880[样例输出]-16838672.6933439.7937509018.566