zoukankan      html  css  js  c++  java
  • 模板—Splay

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define LL long long
    using namespace std;
    struct Splay
    {
        struct node
        {
            int ch[2],fa,val,cnt,siz;
            #define l(x) tr[x].ch[0] 
            #define r(x) tr[x].ch[1]
            #define fa(x) tr[x].fa
            #define val(x) tr[x].val
            #define cnt(x) tr[x].cnt
            #define siz(x) tr[x].siz
        }tr[1000010];
        int sz,root;
        void clear(int x){fa(x)=l(x)=r(x)=val(x)=cnt(x)=siz(x)=0;}
        bool get(int x){return r(fa(x))==x;}
        int newnode(int x)
        {    
            sz++;val(sz)=x;cnt(sz)=siz(sz)=1;
            fa(sz)=l(sz)=r(sz)=0;return sz;
        }
        void pushup(int x)
        {
            if(!x)return;
            siz(x)=cnt(x);
            if(l(x))siz(x)+=siz(l(x));
            if(r(x))siz(x)+=siz(r(x));
        }
        void rotate(int x)
        {
            int old=fa(x),oldf=fa(old),which=get(x);
            tr[old].ch[which]=tr[x].ch[which^1];fa(tr[old].ch[which])=old;
            tr[x].ch[which^1]=old;fa(old)=x;fa(x)=oldf;
            if(oldf)tr[oldf].ch[tr[oldf].ch[1]==old]=x;
            pushup(old);pushup(x);
        }
        void splay(int x)
        {
            for(int f;f=fa(x);rotate(x))
            if(fa(f))rotate((get(x)==get(f))?f:x);
            root=x;
        }
        void insert(int x)
        {    
            if(!root){root=newnode(x);return;}
            int now=root,fa=0;
            while(1)
            {
                if(x==val(now)){cnt(now)++,pushup(now),pushup(fa);splay(now);return;}
                fa=now,now=tr[now].ch[val(now)<x];
                if(!now)
                {
                    int tem=newnode(x);
                    tr[fa].ch[x>val(fa)]=tem;
                    fa(tem)=fa;val(tem)=x;
                    pushup(fa);splay(tem);return;
                }
            }
        }
        int rnk(int x)
        {
            int now=root,ans=0;
            while(1)
            {
                if(x<val(now))now=l(now);
                else
                {
                    ans+=siz(l(now));
                    if(x==val(now)){splay(now);return ans+1;}
                    ans+=cnt(now);now=r(now);
                }
            }
        }
        int kth(int x)
        {
            int now=root;
            while(1)
            {
                if(l(now)&&x<=siz(l(now)))now=l(now);
                else
                {
                    int tem=siz(l(now))+cnt(now);
                    if(x<=tem)return val(now);
                    x-=tem;now=r(now);
                }
            }
        }
        int pre(){int now=l(root);while(r(now))now=r(now);return now;}
        int nxt(){int now=r(root);while(l(now))now=l(now);return now;}
        void del(int x)
        {
            rnk(x);
            if(cnt(root)>1){cnt(root)--;pushup(root);return;}
            if(!l(root)&&!r(root)){clear(root);root=0;return;}
            if(!l(root)){int rt=root;root=r(rt);fa(root)=0;clear(rt);return;}
            if(!r(root)){int rt=root;root=l(rt);fa(root)=0;clear(rt);return;}
            int oldrt=root,leftbig=pre();
            splay(leftbig);r(root)=r(oldrt);
            fa(r(oldrt))=root;clear(oldrt);pushup(root);
        }
    }T;
    signed main()
    {
        int n;cin>>n;int opt,x;
        for(int i=1;i<=n;i++)
        {    
            cin>>opt>>x;
            if(opt==1)T.insert(x);
            if(opt==2)T.del(x);
            if(opt==3)cout<<T.rnk(x)<<endl;
            if(opt==4)cout<<T.kth(x)<<endl;
            if(opt==5){T.insert(x);cout<<T.val(T.pre())<<endl;T.del(x);}
            if(opt==6){T.insert(x);cout<<T.val(T.nxt())<<endl;T.del(x);}
        }
    }
    View Code

    一个封装比较好的splay板子,不过不知道为啥常数稍大。

    UPD:又打了一个,还好点

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define LL long long
    using namespace std;
    struct Splay
    {
    	#define N 300010
    	int ch[N][2],fa[N],siz[N],key[N],cnt[N];
    	int sz,rt;
    	void clear(int x){ch[x][0]=ch[x][1]=fa[x]=siz[x]=key[x]=cnt[x]=0;}
    	int get(int x){return ch[fa[x]][1]==x;}
    	void pushup(int x)
    	{
    		if(!x)return;siz[x]=cnt[x];
    		if(ch[x][0])siz[x]+=siz[ch[x][0]];
    		if(ch[x][1])siz[x]+=siz[ch[x][1]];
    	}
    	void rotate(int x)
    	{
    		int wh=get(x),f=fa[x],of=fa[f];
    		ch[f][wh]=ch[x][wh^1];fa[ch[f][wh]]=f;
    		ch[x][wh^1]=f;fa[f]=x;fa[x]=of;
    		if(of)ch[of][ch[of][1]==f]=x;
    		pushup(f);pushup(x);
    	}
    	void splay(int x)
    	{
    		for(int f;f=fa[x];rotate(x))
    		if(fa[f])rotate((get(x)==get(f))?f:x);
    		rt=x;
    	}
    	int node(int x){++sz,siz[sz]=cnt[sz]=1;key[sz]=x;fa[sz]=ch[sz][0]=ch[sz][1]=0;return sz;}
    	void insert(int x)
    	{	
    		if(!rt){rt=node(x);return;}
    		int now=rt,f=0;
    		while(1)
    		{
    			if(key[now]==x){cnt[now]++,pushup(now),pushup(f);splay(now);return;}
    			f=now;now=ch[now][x>key[now]];
    			if(!now)
    			{	
    				int tem=node(x);ch[f][x>key[f]]=tem;
    				fa[tem]=f;pushup(f);pushup(tem);splay(tem);return;
    			}
    		}
    	}
    	int kth(int k)
    	{
    		int p=rt;
    		while(1)
    		{
    			if(ch[p][0]&&siz[ch[p][0]]>=k)p=ch[p][0];
    			else if(siz[ch[p][0]]+cnt[p]>=k)return key[p];
    			else k-=siz[ch[p][0]]+cnt[p],p=ch[p][1];
    		}
    	}
    	int rnk(int x)
    	{
    		int p=rt,al=0;
    		while(1)
    		{	
    			if(x<key[p])p=ch[p][0];
    			else 
    			{
    				al+=siz[ch[p][0]];
    				if(x==key[p]){splay(p);return al+1;}
    				al+=cnt[p];p=ch[p][1];
    			}
    		}
    	}
    	int pre(){int now=ch[rt][0];while(ch[now][1])now=ch[now][1];return now;}
    	int nxt(){int now=ch[rt][1];while(ch[now][0])now=ch[now][0];return now;}
    	void del(int x)
    	{	
    		rnk(x);
    		if(cnt[rt]>1){cnt[rt]--;pushup(rt);return;}
    		if(!ch[rt][0]&&!ch[rt][1]){clear(rt);rt=0;return;}
    		if(!ch[rt][0]){int root=rt;rt=ch[rt][1];fa[rt]=0;clear(root);return;}
    		if(!ch[rt][1]){int root=rt;rt=ch[rt][0];fa[rt]=0;clear(root);return;}
    		int oldrt=rt,leftbig=pre();
    		splay(leftbig);ch[rt][1]=ch[oldrt][1];
    		fa[ch[oldrt][1]]=rt;clear(oldrt);pushup(rt);
    	}
    }T;
    signed main()
    {
    	int n;cin>>n;int opt,x;
    	for(int i=1;i<=n;i++)
    	{	
    		cin>>opt>>x;
    		if(opt==1)T.insert(x);
    		if(opt==2)T.del(x);
    		if(opt==3)cout<<T.rnk(x)<<endl;
    		if(opt==4)cout<<T.kth(x)<<endl;
    		if(opt==5){T.insert(x);cout<<T.key[T.pre()]<<endl;T.del(x);}
    		if(opt==6){T.insert(x);cout<<T.key[T.nxt()]<<endl;T.del(x);}
    	}
    }
    
  • 相关阅读:
    100篇论文
    Tengine vs openresty
    Dottrace跟踪代码执行时间
    Linux Server
    Linux+Apache+Mysql+Php
    linux+nginx+mysql+php
    tshark命令行的使用(转)
    tcpdump VS tshark用法(转)
    Lua语言在Wireshark中使用(转)
    doc-remote-debugging.html
  • 原文地址:https://www.cnblogs.com/Al-Ca/p/11576179.html
Copyright © 2011-2022 走看看