求助Splay模板题,/kk
查看原帖
求助Splay模板题,/kk
84025
Kiel楼主2021/10/14 15:47
#include<cmath>
#include<stack>
#include<queue>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 1e9
#define mp make_pair
#define pii pair<int,int> 
using namespace std;
typedef long long ll;
inline int rd(){char c=getchar();int tot=1;while ((c<'0'|| c>'9')&&c!='-') c=getchar();if (c=='-'){tot=-1;c=getchar();}
ll sum=0;while (c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*tot;}
const int N=1e5+100;const ll mod=998244353;
struct Splay{
   int ch[N][2],v[N],nm[N],fa[N],sz[N],rt,tot;
   int is(int x){
   	return (ch[fa[x]][0]==x?0:1);
   }
   void pushup(int x){
   	sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+nm[x];
   }
   void rotate(int x){
   	int y=fa[x],z=fa[y],f1=is(x),f2=is(y);
   	ch[y][f1]=ch[x][f1^1];fa[ch[x][f1^1]]=y;
   	ch[x][f1^1]=y;fa[y]=x;
   	ch[z][f2]=x,fa[x]=z;
   	pushup(y),pushup(x);
   }
   void splay(int x,int to){
   	while(fa[x]!=to){
   		int y=fa[x],z=fa[y];
   		if(z!=to)if(is(x)^is(y))rotate(y);else rotate(x);
   		rotate(x);
   	}
   	if(!to)rt=x;
   }
   void updata(int &x,int vl,int f){
   	if(!x){
   		v[x=++tot]=vl;nm[x]=1;fa[x]=f;sz[x]=1;
   		splay(x,0);
   		return ;
   	}
   	if(v[x]==vl)nm[x]++,sz[x]++,splay(x,0);
   	else{
   		if(vl<v[x])updata(ch[x][0],vl,x);
   		else updata(ch[x][1],vl,x);
   	}
   }
   int queryrk(int vl){
   	int x=rt,k=0;
   	while(x){
   		if(v[x]==vl){
   			k+=sz[ch[x][0]]+1;
   			splay(x,0);
   			break;
   		}
   		else if(v[x]>vl)x=ch[x][0];
   		else k+=sz[ch[x][0]]+nm[x],x=ch[x][1];
   	}
   	return k;
   }
   int queryvl(int k){
   	int x=rt;
   	while(x){
   		if(k>=sz[ch[x][0]]+1&&k<=sz[ch[x][0]]+nm[x]){
   			splay(x,0);
   			return v[x];
   		}
   		else if(k>sz[ch[x][0]]+nm[x])k-=(sz[ch[x][0]]+nm[x]),x=ch[x][1];
   		else x=ch[x][0];
   	}
   }
   int findpre(int vl){
   	int x=rt,Max=-inf;
   	while(x){
   		if(v[x]<vl)Max=max(Max,v[x]),x=ch[x][1];
   		else if(v[x]>=vl)x=ch[x][0];
   	}
   	return Max;
   }
   
   int findsuf(int vl){
   	int x=rt,Min=inf;
   	//printf("%d\n",x);
   	while(x){
   		//printf("find %d %d\n",x,v[x]);
   		if(v[x]>vl)Min=min(Min,v[x]),x=ch[x][0];
   		else x=ch[x][1];
   	}
   	return Min;
   }
   int find(int vl){
   	int x=rt;
   	while(x){
   		if(v[x]==vl)return x;
   		else if(v[x]>vl)x=ch[x][0];
   		else x=ch[x][1];
   	}
   }
   void del(int vl){
   	int x=find(vl);splay(x,0);
   	//printf("del %d=%d %d %d\n",v[x],ch[x][0],ch[x][1]);
   	if(--nm[x])return ;
   	if(!ch[x][0]&&!ch[x][1])rt=0;
   	else if(!ch[x][1])rt=ch[x][0],fa[rt]=0,pushup(rt);
   	else if(!ch[x][0])rt=ch[x][1],fa[rt]=0,pushup(rt);
   	else{
   		x=ch[x][0];
   		while(ch[x][1])x=ch[x][1];
   		splay(x,0);
   		int y=ch[x][1],z=ch[y][1];
   		//printf("%d %d %d\n",v[x],v[y],v[z]);
   		ch[x][1]=z;fa[z]=y;pushup(x);
   	}
   	//printf("rt:%d %d\n",rt,v[rt]);
   }
   void dfs(int x){
   	if(!x)return ;
   	dfs(ch[x][0]);
   	printf("%d(%d)",v[x],nm[x]);	
   	dfs(ch[x][1]);
   }
}T;
int t;
int main(){
//	freopen("data.in","r",stdin); 
//	freopen("data.out","w",stdout);
   t=rd();
   while(t--){
   	int opt=rd();
   	if(opt==1)T.updata(T.rt,rd(),0),T.splay(T.tot,0);
   	else if(opt==2)T.del(rd());
   	else if(opt==3)printf("%d\n",T.queryrk(rd()));
   	else if(opt==4)printf("%d\n",T.queryvl(rd()));
   	else if(opt==5)printf("%d\n",T.findpre(rd()));
   	else if(opt==6)printf("%d\n",T.findsuf(rd()));
   	//printf("%d:\n",T.rt);T.dfs(T.rt);puts("");
   }
   return 0;
}
/*
10
1 15
1 10
1 5
1 20
4 1
15
*/
2021/10/14 15:47
加载中...