【总结】Splay和各种题目

Splay是平衡树的变种之一,希望大家不要掌握按照Anson的说法,能不写平衡树就不写

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
int n,m;
class BST{
private:
	struct node{
		int ch[2];
		int val,ff,size,cnt,mark;
	}t[500010];
	int root,tot;
	void pushup(int o){
		t[o].size=t[t[o].ch[0]].size+t[t[o].ch[1]].size+t[o].cnt;
	}
	void pushdown(int o){
		if(t[o].mark){
			t[t[o].ch[0]].mark^=1;
			t[t[o].ch[1]].mark^=1;
			t[o].mark=0;
			swap(t[o].ch[0],t[o].ch[1]);
		}
	}
	void rotate(int x){
		int y=t[x].ff,z=t[y].ff;
		int k=(t[y].ch[1]==x);
		t[z].ch[t[z].ch[1]==y]=x;
		t[x].ff=z;t[y].ch[k]=t[x].ch[k^1];
		t[t[x].ch[k^1]].ff=y;
		t[x].ch[k^1]=y;t[y].ff=x;
		pushup(x);pushup(y);
	}
public:
	void Splay(int x,int goal){
		while(t[x].ff!=goal){
			int y=t[x].ff,z=t[y].ff;
			if(z!=goal)
				(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
			rotate(x);
		}
		if(!goal)root=x;
	}
	void Insert(int x){
		int u=root,ff=0;
		while(u && t[u].val!=x){
			ff=u;
			u=t[u].ch[x>t[u].val];
		}
		if(u)t[u].cnt++;
		else{
			u=++tot;
			if(ff)t[ff].ch[x>t[ff].val]=u;
			t[u].ch[0]=t[u].ch[1]=0;
			t[u].ff=ff;t[u].size=t[u].cnt=1;
			t[u].val=x;
		}
		Splay(u,0);
	}
 	int kth(int x){
		int u=root;
		while(9247){
			pushdown(u);
			int y=t[u].ch[0];
			if(x>t[y].size+t[u].cnt){
				x-=t[y].size+t[u].cnt;
				u=t[u].ch[1];
			}
			else
				if(t[y].size>=x)u=y;
				else return t[u].val;
		}
	}
	void Work(int l,int r){
		l=kth(l);
		r=kth(r+2);
		Splay(l,0);Splay(r,l);
		t[t[t[root].ch[1]].ch[0]].mark^=1;
	}
	void write(int u){
		pushdown(u);
		if(t[u].ch[0])write(t[u].ch[0]);
		if(t[u].val>1 && t[u].val<n+2)printf("%d ",t[u].val-1);
		if(t[u].ch[1])write(t[u].ch[1]);
	}
	void print(){
		write(root);
	}
}Splay;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n+2;i++)Splay.Insert(i);
	while(m--){
		int l,r;scanf("%d%d",&l,&r);
		Splay.Work(l,r);
	}
	Splay.print();
	puts("");
	return 0;
}

以下是文艺平衡树

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
int n,m;
class BST{
private:
	struct node{
		int ch[2];
		int val,ff,size,cnt,mark;
	}t[500010];
	int root,tot;
	void pushup(int o){
		t[o].size=t[t[o].ch[0]].size+t[t[o].ch[1]].size+t[o].cnt;
	}
	void pushdown(int o){
		if(t[o].mark){
			t[t[o].ch[0]].mark^=1;
			t[t[o].ch[1]].mark^=1;
			t[o].mark=0;
			swap(t[o].ch[0],t[o].ch[1]);
		}
	}
	void rotate(int x){
		int y=t[x].ff,z=t[y].ff;
		int k=(t[y].ch[1]==x);
		t[z].ch[t[z].ch[1]==y]=x;
		t[x].ff=z;t[y].ch[k]=t[x].ch[k^1];
		t[t[x].ch[k^1]].ff=y;
		t[x].ch[k^1]=y;t[y].ff=x;
		pushup(x);pushup(y);
	}
public:
	void Splay(int x,int goal){
		while(t[x].ff!=goal){
			int y=t[x].ff,z=t[y].ff;
			if(z!=goal)
				(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
			rotate(x);
		}
		if(!goal)root=x;
	}
	void Insert(int x){
		int u=root,ff=0;
		while(u && t[u].val!=x){
			ff=u;
			u=t[u].ch[x>t[u].val];
		}
		if(u)t[u].cnt++;
		else{
			u=++tot;
			if(ff)t[ff].ch[x>t[ff].val]=u;
			t[u].ch[0]=t[u].ch[1]=0;
			t[u].ff=ff;t[u].size=t[u].cnt=1;
			t[u].val=x;
		}
		Splay(u,0);
	}
 	int kth(int x){
		int u=root;
		while(9247){
			pushdown(u);
			int y=t[u].ch[0];
			if(x>t[y].size+t[u].cnt){
				x-=t[y].size+t[u].cnt;
				u=t[u].ch[1];
			}
			else
				if(t[y].size>=x)u=y;
				else return t[u].val;
		}
	}
	void Work(int l,int r){
		l=kth(l);
		r=kth(r+2);
		Splay(l,0);Splay(r,l);
		t[t[t[root].ch[1]].ch[0]].mark^=1;
	}
	void write(int u){
		pushdown(u);
		if(t[u].ch[0])write(t[u].ch[0]);
		if(t[u].val>1 && t[u].val<n+2)printf("%d ",t[u].val-1);
		if(t[u].ch[1])write(t[u].ch[1]);
	}
	void print(){
		write(root);
	}
}Splay;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n+2;i++)Splay.Insert(i);
	while(m--){
		int l,r;scanf("%d%d",&l,&r);
		Splay.Work(l,r);
	}
	Splay.print();
	puts("");
	return 0;
}
posted @ 2018-10-25 21:32  cj_gjh  阅读(524)  评论(0编辑  收藏  举报