题目:
http://poj.org/problem?id=3481
题意:
有一组操作,有如下三种:
- 0,结束操作
- 1 k p,把一个客户k加入到队列中,优先级为p
- 2, 把队列中优先级最高的客户取出来
- 3, 把队列中优先级最低的客户取出来
用
SBTree
和
treap
写的
SBTree:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100000 + 10, INF = 0x3f3f3f3f;
struct node
{
int val, sz, son[2];
int id;
void init(int _val, int _sz, int _id)
{
val = _val, sz = _sz, id = _id;
son[0] = son[1] = 0;
}
};
struct SBTree
{
int tot, root;
node tr[N];
void init()
{
tot = 0, root = 0;
tr[0].init(0, 0, 0);
}
void update(int x)
{
tr[x].sz = tr[tr[x].son[0]].sz + tr[tr[x].son[1]].sz + 1;
}
void rotate(int &x, int p)
{
int y = tr[x].son[!p];
tr[x].son[!p] = tr[y].son[p];
tr[y].son[p] = x;
update(x), update(y);
x = y;
}
void maintain(int &x, int p)
{
if(tr[tr[tr[x].son[p]].son[p]].sz > tr[tr[x].son[!p]].sz)
rotate(x, !p);
else if(tr[tr[tr[x].son[p]].son[!p]].sz > tr[tr[x].son[!p]].sz)
rotate(tr[x].son[p], p), rotate(x, !p);
else return;
maintain(tr[x].son[0], 0);
maintain(tr[x].son[1], 1);
maintain(x, 0);
maintain(x, 1);
}
void insert(int &x, int val, int id)
{
if(x == 0) tr[x = ++tot].init(val, 1, id);
else
{
tr[x].sz++;
int p = val > tr[x].val;
insert(tr[x].son[p], val, id);
maintain(x, p);
}
}
//用此删除函数时,待删除的节点可以不存在
// bool del_node(int &x, int val)
// {
// if(x == 0) return false;
// if(tr[x].val == val)
// {
// if(tr[x].son[0] && tr[x].son[1])
// {
// int y = get_pre(x);
// tr[x].val = tr[y].val;
// tr[x].sz--;
// return del_node(tr[x].son[0], tr[x].val);
// }
// else
// {
// x = tr[x].son[0] + tr[x].son[1];
// return true;
// }
// }
// else
// {
// int p = val > tr[x].val;
// if(del_node(tr[x].son[p], val))
// {
// tr[x].sz--; return true;
// }
// else return false;
// }
// }
void del_node(int &x, int val)
{
if(tr[x].val == val)
{
if(tr[x].son[0] && tr[x].son[1])
{
int y = get_pre(x);
tr[x].val = tr[y].val;
tr[x].sz--;
del_node(tr[x].son[0], tr[x].val);
}
else x = tr[x].son[0] + tr[x].son[1];
}
else
{
tr[x].sz--;
int p = val > tr[x].val;
del_node(tr[x].son[p], val);
}
}
int get_pre(int x) //返回前驱的下标
{
int y = tr[x].son[0];
while(tr[y].son[1]) y = tr[y].son[1];
return y;
}
int get_sub(int x) //返回后继的下标
{
int y = tr[x].son[1];
while(tr[y].son[0]) y = tr[y].son[0];
return y;
}
int get_kth(int x, int k) //得到第k小值
{
if(k == tr[tr[x].son[0]].sz + 1) return tr[x].val;
else if(k > tr[tr[x].son[0]].sz + 1) return get_kth(tr[x].son[1], k - tr[tr[x].son[0]].sz - 1);
else return get_kth(tr[x].son[0], k);
}
int get_rank(int x, int val) //得到val从小到大的排名
{
if(val == tr[x].val) return tr[tr[x].son[0]].sz + 1;
else if(val > tr[x].val) return get_rank(tr[x].son[1], val) + tr[tr[x].son[0]].sz + 1;
else return get_rank(tr[x].son[0], val);
}
int get_max_min(int x, int p)//得到最大值或者最小值
{
while(tr[x].son[p]) x = tr[x].son[p];
return x;
}
}sbt;
int main()
{
int op, k, p;
sbt.init();
while(scanf("%d", &op), op)
{
if(op == 1)
{
scanf("%d%d", &k, &p);
sbt.insert(sbt.root, p, k);
}
else if(op == 2)
{
int x = sbt.get_max_min(sbt.root, 1);
printf("%d\n", sbt.tr[x].id);
sbt.del_node(sbt.root, sbt.tr[x].val);
}
else
{
int x = sbt.get_max_min(sbt.root, 0);
printf("%d\n", sbt.tr[x].id);
sbt.del_node(sbt.root, sbt.tr[x].val);
}
}
return 0;
}
treap:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100000 + 10;
struct node
{
int val, pri, son[2];
int id;
void init(int _val, int _id, int _pri)
{
val = _val, id = _id, pri = pri;
son[0] = son[1] = 0;
}
};
struct Treap
{
int tot, root;
node tr[N];
void init()
{
tot = 0, root = 0;
tr[0].init(0, 0, 0);
}
void rotate(int &x, int p)
{
int y = tr[x].son[!p];
tr[x].son[!p] = tr[y].son[p];
tr[y].son[p] = x;
x = y;
}
void insert(int &x, int val, int id)
{
if(x == 0) tr[x = ++tot].init(val, id, rand());
else
{
int p = val > tr[x].val;
insert(tr[x].son[p], val, id);
if(tr[x].pri < tr[tr[x].son[p]].pri) rotate(x, !p);
}
}
void del_node(int &x, int val)
{
if(tr[x].val == val)
{
if(tr[x].son[0] && tr[x].son[1])
{
int p = tr[tr[x].son[0]].pri > tr[tr[x].son[1]].pri;
rotate(x, p);
del_node(tr[x].son[p], val);
}
else
{
if(tr[x].son[0] != 0) x = tr[x].son[0];
else x = tr[x].son[1];
}
}
else
{
int p = val > tr[x].val;
del_node(tr[x].son[p], val);
}
}
int get(int x, int p)
{
while(tr[x].son[p]) x = tr[x].son[p];
return x;
}
}treap;
int main()
{
int op, id, val;
treap.init();
while(scanf("%d", &op), op)
{
if(op == 1)
{
scanf("%d%d", &id, &val);
treap.insert(treap.root, val, id);
}
else if(op == 2)
{
int x = treap.get(treap.root, 1);
printf("%d\n", treap.tr[x].id);
treap.del_node(treap.root, treap.tr[x].val);
}
else if(op == 3)
{
int x = treap.get(treap.root, 0);
printf("%d\n", treap.tr[x].id);
treap.del_node(treap.root, treap.tr[x].val);
}
}
return 0;
}