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;
    			}
    		}
    	}
    }
    
  • 相关阅读:
    LOJ#3212. 「CSP-S 2019」划分
    矩阵乘法
    SSF信息社团4月训练题目整理
    AtCoder Regular Contest 116
    SSF信息社团3月训练题目整理
    Codeforces Round #704 (Div. 2)
    SSF信息社团寒假训练题目整理(三)
    关于 zzt 得 0.8 分这件事
    Luogu P7244 章节划分
    SSF信息社团寒假训练题目整理(二)
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366342.html
Copyright © 2011-2022 走看看