zoukankan      html  css  js  c++  java
  • 【TYVJ1728】【洛谷P3369】—普通平衡树(Splay写法)

    传送门

    这年头找个好点的SplaySplay板子好难的

    还是看的yybyyb

    操作都是常规的,对着代码看一下就懂了

    注意由于deletedelete的方法比较特殊,需要对前驱后继操作

    所以为了保证每次都一定有前驱后继要先加一个极大值和一个极小值

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    	return res*f;
    }
    const int N=100006;
    int n,m,rt,tot;
    int fa[N],siz[N],son[N][2],val[N],cnt[N];
    #define lc(u) (son[u][0])
    #define rc(u) (son[u][1])
    inline void pushup(int u){
    	siz[u]=siz[lc(u)]+siz[rc(u)]+cnt[u];
    }
    inline void rotate(int v){
    	int u=fa[v],z=fa[u];
    	int t=(rc(u)==v);
    	son[z][rc(z)==u]=v;
    	fa[v]=z;
    	son[u][t]=son[v][t^1];
    	fa[son[v][t^1]]=u;
    	fa[u]=v,son[v][t^1]=u;
    	pushup(u),pushup(v);
    }
    inline void splay(int v,int goal){
    	while(fa[v]!=goal){
    		int u=fa[v],z=fa[u];
    		if(z!=goal)
    			(lc(z)==u)^(lc(u)==v)?rotate(v):rotate(u);
    		rotate(v);
    	}
    	if(goal==0)rt=v;
    }
    inline void insert(int x){
    	int u=rt,f=0;
    	while(u&&val[u]!=x){
    		f=u,u=son[u][x>val[u]];
    	}
    	if(u)cnt[u]++;
    	else{
    		u=++tot;
    		if(f)son[f][x>val[f]]=u;
    		lc(u)=rc(u)=0;
    		fa[u]=f,val[u]=x,siz[u]=cnt[u]=1;
    	}
    	splay(u,0);
    }
    inline void find(int x){
    	int u=rt;
    	if(!u)return;
    	while(son[u][x>val[u]]&&val[u]!=x)
    		u=son[u][x>val[u]];
    	splay(u,0);
    }
    inline int pre(int x){
    	find(x);
    	int u=rt;
    	if(val[u]<x)return u;
    	u=lc(u);
    	while(rc(u))u=rc(u);
    	return u;
    }
    inline int nxt(int x){
    	find(x);
    	int u=rt;
    	if(val[u]>x)return u;
    	u=rc(u);
    	while(lc(u))u=lc(u);
    	return u;
    }
    inline void delet(int x){
    	int last=pre(x),next=nxt(x);
    	splay(last,0),splay(next,last);
    	int del=lc(next);
    	if(cnt[del]>1)cnt[del]--,splay(del,0);
    	else lc(next)=0;
    }
    inline int kth(int x){
    	int u=rt;
    	if(siz[u]<x)return 0;
    	while(1){
    		int y=lc(u);
    		if(x>siz[y]+cnt[u]){
    			x-=siz[y]+cnt[u];
    			u=rc(u);
    		}
    		else {
    			if(x<=siz[y]){
    				u=y;
    			}
    			else return val[u];
    		}
    	}
    }
    int main(){
    	n=read();
    	insert(20030224);
    	insert(-20030224);
    	for(int i=1;i<=n;i++){
    		int op=read(),x=read();
    		switch(op){
    			case 1:{
    				insert(x);
    				break;
    			}
    			case 2:{
    				delet(x);
    				break;
    			}
    			case 3:{
    				find(x);
    				cout<<siz[lc(rt)]<<'
    ';
    				break;
    			}
    			case 4:{
    				cout<<kth(x+1)<<'
    ';
    				break;
    			}
    			case 5:{
    				cout<<val[pre(x)]<<'
    ';
    				break;
    			}
    			case 6:{
    				cout<<val[nxt(x)]<<'
    ';
    				break;
    			}
    		}
    	}
    }
    
  • 相关阅读:
    为mongoDB加用户权限管理
    手机号归属地查询接口
    关于微信小程序
    linux交互执行命令,expect
    apache配置跨域请求代理
    Linux(Mac)常用命令
    解决:配置虚拟主机,重启apache,[warn] _default_ VirtualHost overlap on port 80, the first has precedence
    linux下grep分析apache日志的命令集合
    解决Macbook Pro蓝牙不可用问题
    Apache如何开启Gzip压缩
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366342.html
Copyright © 2011-2022 走看看