POJ 3481
熟悉了下splay树关于insert和erase的操作,然而关于边界条件的判断还需要有进一步地体会,主要就是在当前节点如果是Null或root之类特殊值,这就要求对于树的结构有很深刻理解。
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <map>
#include <set>
#include <deque>
using namespace std;
const int maxk= 1e6+5;
const int maxp= 1e7+5;
struct Node;
Node *null;
struct Node
{
Node *ch[2], *fa;
int id, pri, size;
void enVal(int id, int pri)
{
this->id= id;
this->pri= pri;
}
void clear()
{
ch[0]= ch[1]= fa= null;
size= 1;
}
void setc(Node *p, int d)
{
if (this== null){
return;
}
ch[d]= p;
p->fa= this;
}
void pushUp()
{
if (this== null){
return;
}
size= ch[0]->size+ch[1]->size+1;
}
int d()
{
return fa->ch[1]== this;
}
};
Node pool[maxk], *tail, *root;
int op, id, pri;
void Rotate(Node *x)
{
if (x->fa== null){
return;
}
Node *f= x->fa, *ff= x->fa->fa;
int c= x->d(), cc= f->d();
f->setc(x->ch[!c], c);
x->setc(f, !c);
if (ff->ch[cc]== f){
ff->setc(x, cc);
}
else{
x->fa= ff;
}
f->pushUp();
x->pushUp();
}
inline void Splay(Node *&root, Node *x, Node * const goal)
{
while (goal!= x->fa){
if (goal== x->fa->fa){
Rotate(x);
}
else{
int c= x->d(), cc= x->fa->d();
c == cc ? Rotate(x->fa) : Rotate(x);
Rotate(x);
}
}
x->pushUp();
if (goal== null){
root= x;
}
}
Node *get_kth(Node *r, int k)
{
if (null== r){
return r;
}
Node *x= r;
while (k!= x->ch[0]->size+1){
if (k<= x->ch[0]->size){
x= x->ch[0];
}
else{
k-= x->ch[0]->size+1;
x= x->ch[1];
}
}
return x;
}
void Erase(Node *&root, Node *x)
{
Splay(root, x, null);
if (x->ch[1]!= null){
root= x->ch[1];
Splay(root, get_kth(root, 1), null);
root->setc(x->ch[0], 0);
}
else{
root= root->ch[0];
}
root->fa= null;
root->pushUp();
}
void Insert(Node *&root, Node *x)
{
if (root== null){
root= x;
return;
}
Node *now= root;
Node *pre= root->fa;
while (now!= null){
pre= now;
now= now->ch[x->pri >= now->pri];
}
x->clear();
pre->setc(x, x->pri >= pre->pri);
Splay(root, x, null);
}
void Init()
{
tail= pool;
null= tail++;
null->ch[0]= null->ch[1]= null->fa= null;
null->size= null->id= null->pri= 0;
root= null;
}
int main(int argc, char const *argv[])
{
Init();
Node *now;
while (~scanf("%d", &op) && op){
if (1== op){
scanf("%d %d", &id, &pri);
now= tail++;
now->clear();
now->enVal(id, pri);
Insert(root, now);
}
else if (2== op){
now= get_kth(root, root->size);
printf("%d\n", now->id);
Erase(root, now);
}
else if (3== op){
now= get_kth(root, 1);
printf("%d\n", now->id);
Erase(root, now);
}
}
return 0;
}