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;
}
posted @ 2021-05-05 10:54  IdiotNe  阅读(38)  评论(0编辑  收藏  举报