• splay学习


    花了一天时间调试终于过了。网上非指针的splay太少了,学长大佬们拒绝指导,只能靠自己了。

    其实splay是为了保证时间复杂度,所以每次操作进行一次splay。

    splay共三种操作:zig,zig_zig,zig_zag。

    设当前点为x,y=fa[x],z=fa[y]

    1.zig

    y为root时直接rotate(x)

    2.zig_zig

    当x,y,z构成一条链时,先rotate(y),再rotate(x)

    3.zig_zag

    当非前两种情况时,做两次rotate(x)

    void splay(int x)
    {
    	for(int fa;(fa=tr[x].f);rotate(x))
    		if(tr[fa].f)
    			rotate((get(fa)==get(x))?fa:x);
    	root=x;
    }
    

     模板题

    ac代码:

    #include<bits/stdc++.h>
    #define maxn 100005
    #define ls tr[x].ch[0]
    #define rs tr[x].ch[1]
    using namespace std;
    struct node{
    	int ch[2],f,key,cnt,size;
    }tr[maxn];
    int sz,root,n;
    void clear(int x)
    {
    	tr[x].ch[1]=tr[x].ch[0]=tr[x].cnt=tr[x].f=tr[x].key=tr[x].size=0;
    }
    int get(int x)
    {
    	return tr[tr[x].f].ch[1]==x;
    }
    void update(int x)
    {
    	if(x)
    	{
    		tr[x].size=tr[x].cnt;
    		if(ls)tr[x].size+=tr[ls].size;
    		if(rs)tr[x].size+=tr[rs].size;		
    	}
    }
    void rotate(int x)
    {
    	int y=tr[x].f,z=tr[y].f,whi=get(x);
    	tr[y].ch[whi]=tr[x].ch[whi^1];tr[tr[y].ch[whi]].f=y;
    	tr[x].ch[whi^1]=y;
    	tr[x].f=z;
    	if(z)tr[z].ch[get(y)]=x;
    	tr[y].f=x;
    	update(y);update(x);
    }
    void splay(int x)
    {
    	for(int fa;(fa=tr[x].f);rotate(x))
    		if(tr[fa].f)
    			rotate((get(fa)==get(x))?fa:x);
    	root=x;
    }
    void insert(int x)
    {
    	if(root==0){root=++sz;tr[sz].key=x;tr[sz].cnt=tr[sz].size=1;return;}
    	int now=root;
    	while(1)
    	{
    		if(tr[now].key==x){tr[now].cnt++;tr[now].size++;splay(now);return;}
    		int fa=now;
    		now=tr[now].ch[tr[now].key<x];
    		if(now==0)
    		{
    			tr[++sz].f=fa;
    			tr[sz].cnt=tr[sz].size=1;
    			tr[sz].key=x;
    			tr[fa].ch[tr[fa].key<x]=sz;
    			update(fa);
    			splay(sz);
    			return;
    		}
    	}
    }
    int find_pm(int x)
    {
    	int now=root,ans=0;
    	while(1)
    	{
    		if(tr[now].key<=x)
    		{
    			ans+=(tr[now].ch[0]?tr[tr[now].ch[0]].size:0);
    			if(tr[now].key==x){splay(now);return ans+1;}
    			ans+=tr[now].cnt;
    			now=tr[now].ch[1];
    		}
    		else now=tr[now].ch[0];
    	}
    }
    int find_wz(int x)
    {
    	int now=root;
    	while(1)
    	{
    		int lsz=tr[tr[now].ch[0]].size;
    		if(lsz>=x)now=tr[now].ch[0];
    		else if(lsz+tr[now].cnt>=x)return tr[now].key;
    		else {
    			x-=lsz+tr[now].cnt;
    			now=tr[now].ch[1];
    		}
    	}
    }
    int pre()
    {
    	int now=tr[root].ch[0],x=tr[root].key;
    	while(tr[now].ch[1]!=0)
    	{
    		now=tr[now].ch[1];
    	}
    	return now;
    }
    int nex()
    {
    	int now=tr[root].ch[1],x=tr[root].key;
    	while(tr[now].ch[0]!=0)
    	{
    		now=tr[now].ch[0];
    	}
    	return now;
    }
    void del(int x)
    {
    	int w=find_pm(x);
    	if(tr[root].cnt>1){tr[root].cnt--;tr[root].size--;return;}
    	if(tr[root].ch[0]==0&&tr[root].ch[1]==0){clear(root);root=0;return;}
    	if(tr[root].ch[0]==0)
    	{
    		int newroot=tr[root].ch[1];
    		clear(root);
    		root=newroot;
    		tr[root].f=0;
    		return;
    	}
    	else if(tr[root].ch[1]==0) 
    	{
    		int newroot=tr[root].ch[0];
    		clear(root);
    		root=newroot;
    		tr[root].f=0;
    		return;
    	}
    	else 
    	{
    		int nowroot=pre(),oldroot=root;
    		splay(nowroot);
    		tr[nowroot].ch[1]=tr[oldroot].ch[1];
    		tr[tr[oldroot].ch[1]].f=nowroot;
    		root=nowroot;
    		tr[root].f=0;
    		clear(oldroot);
    		update(root);
    	}
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		int temp,x;
    		scanf("%d%d",&temp,&x);
    		if(temp==1)insert(x);
    		if(temp==2)del(x);
    		if(temp==3)printf("%d
    ",find_pm(x));
    		if(temp==4)printf("%d
    ",find_wz(x));
    		if(temp==5)insert(x),printf("%d
    ",tr[pre()].key),del(x);
    		if(temp==6)insert(x),printf("%d
    ",tr[nex()].key),del(x);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    jQuery的end() 方法
    jQuery.extend 函数使用详解
    AutoMapper完成Dto与Model的转换
    IoC实践--用Unity实现MVC5.0的IoC控制反转方法
    IoC实践--用Autofac实现MVC5.0的IoC控制反转方法
    Unity依赖注入使用详解
    React+BootStrap+ASP.NET MVC实现自适应和组件的复用
    oracle基础开发工具及常用命令
    Cisco配置发送日志到日志服务器
    Redis讲解
  • 原文地址:https://www.cnblogs.com/hlsb/p/8532377.html
Copyright © 2020-2023  润新知