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