经验证:
Fhq Treap根据二叉堆性质实现的优先队列,是没有问题的
(因为我已经试过了一些题)
我们如想要更改出队优先级,其实很简单,我们只需要改变递归的方向即可,一直向左递归到最终的叶子节点,是最小,同理向右是最大
封装优先队列函数:
struct queue
{
const int base = 131;
int su = 1;
int ran()
{
su = su * base % 1000007;
return su;
}
struct node
{
int ls, rs, w, key;
int sizx;
} tr[maxn * 32];
int cnt, rt;
int newnode(int w)
{
tr[++cnt].key = ran();
tr[cnt].w = w, tr[cnt].sizx = 1;
return cnt;
}
void split(int rt, int w, int &x, int &y)
{
if (!rt)
x = y = 0;
else
{
if (tr[rt].w <= w)
{
x = rt, split(tr[rt].rs, w, tr[rt].rs, y);
}
else
{
y = rt, split(tr[rt].ls, w, x, tr[rt].ls);
}
}
}
int x, y, z;
int join(int x, int y)
{
if (!x || !y)
return x + y;
if (tr[x].key > tr[y].key)
{
tr[x].rs = join(tr[x].rs, y);
return x;
}
else
{
tr[y].ls = join(x, tr[y].ls);
return y;
}
}
void push(int w)
{
split(rt, w, x, y);
rt = join(join(x, newnode(w)), y);
}
bool empty()
{
if (rt)
return true;
return false;
}
int front()
{
int now = rt;
while (tr[now].ls)
now = tr[now].ls;
return tr[now].w;
}
void pop()
{
int w = front();
split(rt, w, x, y);
split(x, w - 1, x, z);
x = join(x, join(tr[z].ls, tr[z].rs));
rt = join(x, y);
}
} q;