POJ-3481 Double Queue

Double Queue

题意:有一个银行, 现在有3种操作, 1 往机器里插入一个优先度为 k, 编号为 x 的人   2 对机器里的优先度最大的人 处理业务, 输出这个人的标号, 并且从机器里删除中这个人。 3 对机器里的优先度最小的人 处理业务, 输出这个人的标号, 并且从机器里删除中这个人。

题解:splay 转一转 就好了, 没有什么额外的操作。可以先插入一个最大值, 一个最小值, 这样对于删除操作的时候, 每一个数必定会有前驱和后继, 就不需要再讨论有没有的前驱后继的事情了。

代码:

  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 }
View Code

 

posted @ 2018-07-30 10:14  Schenker  阅读(174)  评论(0编辑  收藏  举报