• 【总结】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;
    }
    
  • 相关阅读:
    Python3基础 str """ 多行字符串
    Python3基础 str *运算 重复拼接字符串
    Python3基础 time.localtime 当前系统的年月日 时分秒
    Python3基础 time 索引值访问元组中的年月日时分秒
    Python3基础 sys.path 查看搜索路径变量
    Python3基础 sys.path.append 增加模块的搜索路径
    C#中ListView的简单使用方法
    C#的注释和快速开启工具的命令
    sql server2008安装错误(无法处理异常)
    启动计算机总弹出页面配置问题
  • 原文地址:https://www.cnblogs.com/cjgjh/p/9853070.html
Copyright © 2020-2023  润新知