POJ-3481 Double Queue
题意:有一个银行, 现在有3种操作, 1 往机器里插入一个优先度为 k, 编号为 x 的人 2 对机器里的优先度最大的人 处理业务, 输出这个人的标号, 并且从机器里删除中这个人。 3 对机器里的优先度最小的人 处理业务, 输出这个人的标号, 并且从机器里删除中这个人。
题解:splay 转一转 就好了, 没有什么额外的操作。可以先插入一个最大值, 一个最小值, 这样对于删除操作的时候, 每一个数必定会有前驱和后继, 就不需要再讨论有没有的前驱后继的事情了。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 using namespace std; 7 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); 8 #define LL long long 9 #define ULL unsigned LL 10 #define fi first 11 #define se second 12 #define pb push_back 13 #define lson l,m,rt<<1 14 #define rson m+1,r,rt<<1|1 15 #define max3(a,b,c) max(a,max(b,c)) 16 #define min3(a,b,c) min(a,min(b,c)) 17 typedef pair<int,int> pll; 18 const int inf = 0x3f3f3f3f; 19 const LL INF = 0x3f3f3f3f3f3f3f3f; 20 const LL mod = (int)1e9+7; 21 const int N = 1e6 + 100; 22 int tot = 0, root; 23 int n, m; 24 struct Node{ 25 int son[2], pre; 26 int val, sz, id; 27 void init(int x = 0, int y = 0){ 28 val = x; sz = 1; id = y; 29 pre = son[0] = son[1] = 0; 30 } 31 }tr[N]; 32 void Push_up(int x){ 33 if(!x) return; 34 tr[x].sz = tr[tr[x].son[1]].sz + tr[tr[x].son[0]].sz + 1; 35 } 36 void rotate(int x){ 37 int y = tr[x].pre; 38 int z = tr[y].pre; 39 int k = x == tr[y].son[1]; 40 tr[x].pre = z; 41 tr[z].son[y == tr[z].son[1]] = x; 42 tr[y].son[k] = tr[x].son[k^1]; 43 tr[tr[y].son[k]].pre = y; 44 tr[x].son[k^1] = y; 45 tr[y].pre = x; 46 Push_up(y); 47 } 48 void splay(int x, int goal){ 49 Push_down(x); 50 while(tr[x].pre != goal){ 51 int y = tr[x].pre; 52 int z = tr[y].pre; 53 if(z != goal){ 54 if((tr[y].son[0] == x) ^ (tr[z].son[0] == y)) rotate(x); ///x和y分别是y和z的同一段的儿子 55 else rotate(y); 56 } 57 rotate(x); 58 } 59 if(!goal) root = x; 60 Push_up(x); 61 } 62 int Find(int x, int p){ 63 int &l = tr[p].son[0], &r = tr[p].son[1]; 64 if(x == tr[l].sz + 1) return p; 65 if(x <= tr[l].sz) return Find(x, l); 66 return Find(x- tr[l].sz - 1, r); 67 } 68 69 void Insert(int v, int z){ 70 int p = root, ff = 0; 71 while(p && tr[p].val != v){ 72 ff = p; 73 p = tr[p].son[ tr[p].val < v]; 74 } 75 p = ++tot; 76 if(ff) tr[ff].son[ tr[ff].val < v] = p; 77 tr[p].init(v, z); 78 tr[p].pre = ff; 79 splay(p, 0); 80 } 81 int Next(int x, int f){ 82 int u = root; 83 u = tr[u].son[f]; 84 f ^= 1; 85 while(tr[u].son[f]) u = tr[u].son[f]; 86 return u; 87 } 88 void Delete(int x){ 89 splay(x, 0); 90 int pl = Next(x, 0); 91 int pr = Next(x, 1); 92 splay(pl, 0); 93 splay(pr, pl); 94 tr[pr].son[0] = 0; 95 } 96 int main(){ 97 Insert(inf, 0); 98 Insert(-inf, 0); 99 int totsz = 2; 100 int op, y, z; 101 while(~scanf("%d", &op)){ 102 if(op == 1){ 103 scanf("%d%d", &y, &z); 104 Insert(z, y); 105 totsz++; 106 } 107 else if(totsz == 2) {puts("0");} 108 else { 109 int p; 110 if(op == 2) p = Find(totsz-1, root); 111 if(op == 3) p = Find(2, root); 112 totsz--; 113 printf("%d\n", tr[p].id); 114 Delete(p); 115 } 116 } 117 return 0; 118 }