• 【总结】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;
    }
    
  • 相关阅读:
    JS自定义功能函数实现动态添加网址参数修改网址参数值
    伍、ajax
    类的静态方法(函数)中为什么不能调用非静态成员(属性)?
    android 数据存储 SharePreferences 简单使用
    实现多线程的方式
    线程、进程概念与Android系统组件的关系
    通知—Notifications
    活动栏—Action Bar
    Android菜单—Menu
    对话框控件—Dialog
  • 原文地址:https://www.cnblogs.com/cjgjh/p/9853070.html
Copyright © 2020-2023  润新知