zoukankan      html  css  js  c++  java
  • 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
    ", now->id);
    			Erase(root, now);
    		}
    		else if (3== op){
    			now= get_kth(root, 1);
    			printf("%d
    ", now->id);
    			Erase(root, now);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    C#3.0之神奇的Lambda表达式和Lambda语句
    Expression Tree 学习笔记(一)
    C#对象序列化与反序列化
    Linux Shell编程入门
    ora-03113或者ora-12573 通信通道的文件结束出现异常错误:核心转储
    如何实现文档在线预览
    使用npoi导入Excel
    判断时间(时:分)是否在某个时间段内
    程序员开发时遇到的那些缩写和名词(记录)
    git
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/14731175.html
Copyright © 2011-2022 走看看