• BZOJ3224 普通平衡树


    浅谈(splay)https://www.cnblogs.com/AKMer/p/9979592.html

    浅谈(fhq)_(treap)https://www.cnblogs.com/AKMer/p/9981274.html

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3224

    平衡树模板题。

    时间复杂度:(O(nlogn))

    空间复杂度:(O(n))

    (splay)版代码如下:

    #include <cstdio>
    using namespace std;
    
    const int maxn=1e5+5;
    
    int n;
    
    int read() {
        int x=0,f=1;char ch=getchar();
        for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
        return x*f;
    }
    
    struct Splay {
        int tot,root;
        int fa[maxn],son[maxn][2];
        int val[maxn],siz[maxn],cnt[maxn];
    
        int newnode(int v) {
            val[++tot]=v;
            siz[tot]=cnt[tot]=1;
            return tot;
        }
    
        int find(int v) {
            int u=root;
            while(val[u]!=v) {
                if(val[u]>v) {if(son[u][0])u=son[u][0];else break;}
                if(val[u]<v) {if(son[u][1])u=son[u][1];else break;}
            }
            return u;
        }
    
        inline int t(int u) {
            return son[fa[u]][1]==u;
        }
    
        void updata(int p) {
            siz[p]=siz[son[p][0]]+cnt[p]+siz[son[p][1]];
        }
    
        void rotate(int u) {
            int ret=t(u),f=fa[u],s=son[u][ret^1];
            son[f][ret]=s;if(s)fa[s]=f;son[u][ret^1]=f;
            fa[u]=fa[f];if(fa[f])son[fa[f]][t(f)]=u;
            fa[f]=u;updata(f);updata(u);
        }
    
        void splay(int u) {
            while(fa[u]) {
                if(fa[fa[u]]) {
                    if(t(fa[u])==t(u))rotate(fa[u]);
                    else rotate(u);
                }rotate(u);
            }root=u;
        }
        
        void ins(int v) {
            if(!root) {root=newnode(v);return;}
            int u=find(v);
            if(val[u]==v) {siz[u]++;cnt[u]++;splay(u);return;}
            newnode(v);fa[tot]=u;son[u][val[u]<v]=tot;
            splay(tot);
        }
    
        void del(int x) {
            if(!root)return;
            int u=find(x);splay(u);
            if((val[u]!=x)||(--cnt[u])) {siz[u]--;return;}
            if(!son[u][0]&&!son[u][1]) {root=0;return;}
            if(!son[u][0]) {root=son[u][1];fa[root]=0;return;}
            if(!son[u][1]) {root=son[u][0];fa[root]=0;return;}
            int node=son[u][0];while(son[node][1])node=son[node][1];
            fa[son[u][0]]=0;splay(node);
            son[root][1]=son[u][1];fa[son[u][1]]=root;
            updata(root);
        }
    
        int get_rk(int v) {
            int u=find(v);splay(u);
            if(val[u]>=v)return siz[son[u][0]]+1;
            return siz[son[u][0]]+cnt[u]+1;
        }
    
        int get_val(int rk) {
            int u=root;
            while(rk) {
                if(siz[son[u][0]]>=rk)u=son[u][0];
                if(siz[son[u][0]]<rk&&siz[son[u][0]]+cnt[u]>=rk)break;
                if(siz[son[u][0]]+cnt[u]<rk)rk-=siz[son[u][0]]+cnt[u],u=son[u][1];
            }
            return val[u];
        }
    
        int get_pre(int v) {
            int u=find(v);splay(u);
            if(val[u]<v)return val[u];
            int node=son[u][0];
            while(son[node][1])node=son[node][1];
            return val[node];
        }
        
        int get_suc(int v) {
            int u=find(v);splay(u);
            if(val[u]>v)return val[u];
            int node=son[u][1];
            while(son[node][0])node=son[node][0];
            return val[node];
        }
    }T;
    
    int main() {
        n=read();
        for(int i=1;i<=n;i++) {
            int opt=read(),x=read();
            if(opt==1)T.ins(x);
            if(opt==2)T.del(x);
            if(opt==3)printf("%d
    ",T.get_rk(x));
            if(opt==4)printf("%d
    ",T.get_val(x));
            if(opt==5)printf("%d
    ",T.get_pre(x));
            if(opt==6)printf("%d
    ",T.get_suc(x));
        }
        return 0;
    }
    

    (fhq)_(treap)版代码如下:

    #include <ctime>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef pair<int,int> pii;
    
    const int maxn=1e5+5;
    
    int n;
    
    int read() {
    	int x=0,f=1;char ch=getchar();
    	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    	return x*f;
    }
    
    struct fhq_treap {
    	int tot,root;
    	int fix[maxn],son[maxn][2];
    	int val[maxn],siz[maxn],cnt[maxn];
    
    	int newnode(int v) {
    		val[++tot]=v,fix[tot]=rand();
    		cnt[tot]=siz[tot]=1;return tot;
    	}
    
    	void updata(int p) {
    		siz[p]=siz[son[p][0]]+cnt[p]+siz[son[p][1]];
    	}
    
    	pii split(int u,int rk) {
    		if(!rk)return make_pair(0,u);
    		if(rk==siz[u])return make_pair(u,0);
    		if(siz[son[u][0]]>=rk) {
    			pii tmp=split(son[u][0],rk);
    			son[u][0]=tmp.second,updata(u);
    			return make_pair(tmp.first,u);
    		}
    		else {
    			pii tmp=split(son[u][1],rk-siz[son[u][0]]-cnt[u]);
    			son[u][1]=tmp.first,updata(u);
    			return make_pair(u,tmp.second);
    		}
    	}
    
    	int merge(int a,int b) {
    		if(!a||!b)return a+b;
    		if(fix[a]>fix[b])return son[a][1]=merge(son[a][1],b),updata(a),a;
    		return son[b][0]=merge(a,son[b][0]),updata(b),b;
    	}
    
    	int getkth(int u,int v,bool &bo,int delta) {
    		if(!u)return 0;int ans=0;
    		if(val[u]>v)ans=getkth(son[u][0],v,bo,delta);
    		else if(val[u]==v) {
    			if(delta!=-1||cnt[u]!=1)cnt[u]+=delta,siz[u]+=delta,bo=1;
    			return siz[son[u][0]];
    		}
    		else ans=siz[son[u][0]]+cnt[u]+getkth(son[u][1],v,bo,delta);
    		if(bo)siz[u]+=delta;return ans;
    	}
    	
    	void ins(int v) {
    		bool bo=0;int rk=getkth(root,v,bo,1);
    		if(bo)return;pii tmp=split(root,rk);
    		root=merge(tmp.first,merge(newnode(v),tmp.second));
    	}
    
    	void del(int v) {
    		bool bo=0;int rk=getkth(root,v,bo,-1)+1;
    		if(bo)return;pii tmp1=split(root,rk);
    		pii tmp2=split(tmp1.first,rk-1);
    		root=merge(tmp2.first,tmp1.second);
    	}
    
    	int get_rk(int v) {
    		bool bo=0;
    		return getkth(root,v,bo,0)+1;
    	}
    
    	int get_val(int rk) {
    		int u=root;
    		while(rk) {
    			if(siz[son[u][0]]>=rk)u=son[u][0];
    			if(siz[son[u][0]]<rk&&siz[son[u][0]]+cnt[u]>=rk)break;
    			if(siz[son[u][0]]+cnt[u]<rk)rk-=siz[son[u][0]]+cnt[u],u=son[u][1];
    		}
    		return val[u];
    	}
    
    	int get_pre(int v) {
    		int rk=get_rk(v)-1;
    		return get_val(rk);
    	}
    
    	int get_suc(int v) {
    		int rk=get_rk(v+1);
    		return get_val(rk);
    	}
    }T;
    
    int main() {
    	srand(time(0));n=read();
    	for(int i=1;i<=n;i++) {
    		int opt=read(),x=read();
    		if(opt==1)T.ins(x);
    		if(opt==2)T.del(x);
    		if(opt==3)printf("%d
    ",T.get_rk(x));
    		if(opt==4)printf("%d
    ",T.get_val(x));
    		if(opt==5)printf("%d
    ",T.get_pre(x));
    		if(opt==6)printf("%d
    ",T.get_suc(x));
    	}
    	return 0;
    }
    
  • 相关阅读:
    DataGridView 密码列(显示为*号)的设置
    有關界面化學的一些有趣現象
    电商网站需要ICP证吗
    JS 未结束的字符串常量
    Iframe自适应高度
    JS正则表达式
    界面活性劑的作用
    js转义字符
    解决dbo登录名为空的问题
    肌肤弹性胶原蛋白
  • 原文地址:https://www.cnblogs.com/AKMer/p/9985277.html
Copyright © 2020-2023  润新知