Splay板子求助
查看原帖
Splay板子求助
148507
_Imaginary_楼主2022/4/23 22:17
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int rt,tot;
int fa[N],ch[N][2],key[N],cnt[N],sz[N];

void clear(int x)
{
	fa[x]=ch[x][0]=ch[x][1]=cnt[x]=key[x]=sz[x]=0;
	
}
bool get(int x)
{
	return ch[fa[x]][1]==x;
}
void pushup(int x)
{
	if(x)
	{
		sz[x]=cnt[x];
		if(ch[x][0]) sz[x]+=sz[ch[x][0]];
		if(ch[x][1]) sz[x]+=sz[ch[x][1]];
	}
}
/*

		 z          z
		/          //
	   y          x
	  / \  左旋  / \\
	 x   c ---> A   y
	/ \           // \
   A   B          B   C

	k代表左,k^1代表右
*/
void rotate(int x)
{
	int y=fa[x],z=fa[y],k=get(x);
	ch[y][k]=ch[x][k^1];
	fa[ch[x][k^1]]=y;
	ch[x][k^1]=y;
	fa[y]=x;
	fa[x]=z;
	if(z) ch[z][ch[z][1]==y]=x;
	pushup(y);
	pushup(x);
}
void splay(int x,int goal=0)
{
	while(fa[x]!=goal)
	{
		int y=fa[x],z=fa[y];
		if(z!=goal) rotate(get(x)==get(y)?y:x);
		rotate(x);
	}
	if(goal==0) rt=x;
}
void find(int x)
{
	int u=rt;
	if(!u) return;
	while(ch[u][x>key[u]] && x!=key[u])
		u=ch[u][x>key[u]];
	splay(u,0);
}
void insert(int x)
{
	int u=rt,f=0;
	while(u&&key[u]!=x){
		f=u;
		u=ch[u][x>key[u]];
	}
	if(u) cnt[u]++,pushup(u),pushup(f);
	else
	{
		u=++tot;
		key[u]=x;
		sz[u]=cnt[u]=1;
		fa[u]=f;
		ch[u][0]=ch[u][1]=0;
		if(f) ch[f][x>key[f]]=u,pushup(f);
		else rt=u;
	}
	splay(u,0);
}
int query_rank(int x)
{
	int now=rt,ans=0;
	while(1)//now?
	{
		if(x<key[now]) now=ch[now][0];
		else{
			ans+=sz[ch[now][0]];
			if(x==key[now])
			{
				splay(now);
				return ans+1;
			}
			ans+=cnt[now];
			now=ch[now][1];
		}
	}
}
int query_kth(int x)
{
	int now=rt;
	while(1)
	{
		if(ch[now][0]&&x<=sz[ch[now][0]])
			now=ch[now][0];
		else
		{
			int tmp=sz[ch[now][0]]+cnt[now];
			if(x<=tmp) return key[now];
			x-=tmp;
			now=ch[now][1];
		}
	}
}
int pre(int x)
{
    find(x);
    if (key[rt]<x) return rt;
    int u=ch[rt][0];
    while (ch[u][1]) u=ch[u][1];
    return u;
}
int succ(int x)
{
    find(x);
    if (key[rt]>x) return rt;
    int u=ch[rt][1];
    while (ch[u][0]) u=ch[u][0];
    return u;
}
void del(int x)
{
    int p=pre(x),s=succ(x);
    splay(p,0); splay(s,p);
    int del=ch[s][0];
    if(cnt[del]>1) 
	{
        --cnt[del];
        splay(del,0);
    } 
	else ch[s][0]=0;
}
int main()
{
	int n,ta,tb;
	scanf("%d",&n);
	while(n--)
	{
		scanf("%d%d",&ta,&tb);
		if(ta==1) insert(tb);
		if(ta==2) del(tb);
		if(ta==3)
		{
			printf("%d\n",query_rank(tb));
		}
		if(ta==4)
		{
			printf("%d\n",query_kth(tb));
		}
		if(ta==5)
		{
//			find(tb);
			printf("%d\n",key[pre(tb)]);
		}
		if(ta==6)
		{
//			find(tb);
			printf("%d\n",key[succ(tb)]);
		}
	}
	return 0;
}

2022/4/23 22:17
加载中...