最后一次 求大神调 Splay
查看原帖
最后一次 求大神调 Splay
906856
A2_Zenith楼主2024/6/6 18:37

将近一个月没过了。。。。。

孩子还有平衡树专题要讲。。。。。。

#include<bits/stdc++.h>
#define int long long
#define doub long double
#define pii pair<int,int>
#define m_p make_pair
#define fir first
#define sec second
using namespace std;
const int maxn=2e5+7;
struct node{
	int val;
	int cnt;
	int siz;
	int fa;
	int ch[2];
}t[maxn];
#define val(u) t[u].val
#define cnt(u) t[u].cnt
#define siz(u) t[u].siz
#define fa(u) t[u].fa
#define ch(u,b) t[u].ch[b]
int rt,tot; 
void clr(int u){val(u)=cnt(u)=siz(u)=fa(u)=ch(u,0)=ch(u,1)=0;}
void pu(int u){
	siz(u)=cnt(u);
	if(ch(u,0))siz(u)+=siz(ch(u,0));
	if(ch(u,1))siz(u)+=siz(ch(u,1));
}
int dir(int u){return u==ch(fa(u),1);}
int newnode(int v,int f){val(++tot)=v,fa(tot)=f,siz(tot)=cnt(tot)=1;return tot;}
void getlis(int u){
	if(!u)return;
	getlis(ch(u,0));
	for(int i=1;i<=cnt(u);i++){
		cout<<val(u)<<" ";
	}
	getlis(ch(u,1));
}
void link(int u,int f,int d){
	fa(u)=f;
	ch(f,d)=u;
}
void rot(int u){
	int f=fa(u),ff=fa(f),d=dir(u);
	link(u,ff,dir(f));
	link(ch(u,d^1),f,d);
	link(f,u,d^1);
	pu(f),pu(u);
}
void splay(int u,int k){
	while(fa(u)!=k){
		if(fa(fa(u))!=k)dir(u)==dir(fa(u))?rot(fa(u)):rot(u);
		rot(u);
	}
	if(!k)rt=u;
}
pii find(int v){
	int u=rt;
	while(1){
		if(v==val(u))return m_p(u,1);
		int nxt=v<val(u)?0:1;
		if(!ch(u,nxt))return m_p(u,0);
		u=ch(u,nxt);
	}
}
void ins(int v){
	if(!rt){
		rt=newnode(v,0);
		return;
	}
	pii pr=find(v);
	int u=pr.fir,exi=pr.sec;
	if(exi){cnt(u)++,pu(u),pu(fa(u)),splay(u,0);return;}
	else{
		int p=newnode(v,u);
		link(p,u,v>val(u));
		splay(p,0);
		return;
	}
}
void del(int v){
	pii pr=find(v);
	int u=pr.fir,exi=pr.sec;
	if(!exi)return;
	splay(u,0);
	if(cnt(u)>1){cnt(u)--,pu(u),splay(u,0);return;}
	else if(!ch(u,0)&&!ch(u,1)){clr(rt),rt=0;return;}
	else if(!ch(u,0)){fa(ch(u,1))=0,rt=ch(u,1),clr(u);return;}
	else if(!ch(u,1)){fa(ch(u,0))=0,rt=ch(u,0),clr(u);return;}
	else{
		int pl=ch(u,0);
		while(ch(pl,1))pl=ch(pl,1);
		splay(pl,u);
		fa(pl)=0,link(ch(u,1),pl,1),clr(u);
		rt=pl;return;
	}
}
int rk(int v){
	int ans=0;
	int u=rt;
	while(1){
		if(!u)return ans+1;
		if(v<val(u)){u=ch(u,0);continue;}
		ans+=siz(ch(u,0));
		if(v==val(u)){splay(u,0);return ans+1;}
		ans+=cnt(u),u=ch(u,1);
	}
	return ans;
}
int kthe(int k){
	int u=rt;
	while(1){
		if(!u)return false;
		if(ch(u,0)&&k<=siz(ch(u,0))){u=ch(u,0);continue;}
		k-=(siz(ch(u,0))+cnt(u));
		if(k<=0){
			splay(u,0);
			return val(u);
		}
		u=ch(u,1);
	}
}
int pre(int v){
	ins(v);
	int u=find(v).fir;
	splay(u,0);
	int p=ch(u,0);
	if(!p){del(v);return p;}
	while(ch(p,1))p=ch(p,1);
	int ans=val(p);
	del(v);
	return ans;
}
int suc(int v){
	ins(v);
	int u=find(v).fir;
	splay(u,0);
	int p=ch(u,1);
	if(!p){del(v);return p;}
	while(ch(p,0))p=ch(p,0);
	int ans=val(p);
	del(v);
	return ans;
}
signed main(){
	int n;
	cin>>n;
	int lstans=0;
	int xx=0;
	while(n--){
		int op,x;
		cin>>op>>x;
		if(op==1)ins(x);
		else if(op==2)del(x);
		else if(op==3)cout<<rk(x)<<endl;
		else if(op==4)cout<<kthe(x)<<endl;
		else if(op==5)cout<<pre(x)<<endl;
		else if(op==6)cout<<suc(x)<<endl;
	}
}
2024/6/6 18:37
加载中...