Splay求调,前两个点T了,照着模板写的
查看原帖
Splay求调,前两个点T了,照着模板写的
537784
saumtam楼主2024/1/10 15:09
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls(r) tr[r].ch[0]
#define rs(r) tr[r].ch[1]
const ll dd=1e5+5,INF=0x3f3f3f3f;
inline ll read(){
	ll x=0,f=0;char c=getchar();
	while(c<'0'||c>'9'){f|=c=='-';c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return f?-x:x;
}
struct Splay{
	ll ch[2],sz,val,cnt;
}tr[5*dd];
ll rt,pcnt,fa[5*dd];
inline void pushup(ll r){
	if(!r) return;
	tr[r].sz=tr[ls(r)].sz+tr[rs(r)].sz+tr[r].cnt;
}
inline void rote(ll x){
	ll y=fa[x],z=fa[y],flg=(x==rs(fa[x]));
	tr[y].ch[flg]=tr[x].ch[!flg];
	if(tr[x].ch[!flg]) fa[tr[x].ch[!flg]]=y;
	tr[x].ch[!flg]=y;
	fa[y]=x,fa[x]=z;
	if(z) tr[z].ch[y==rs(z)]=x;
	pushup(y),pushup(x);
}
inline void splay(ll x){
	for(ll y;(y=fa[x]);rote(x))
	if(fa[y]) rote(((rs(fa[y])==y)==(rs(y)==x))?y:x);
	rt=x;
}
inline void ins(ll x){
	if(!rt){
		tr[++pcnt].val=x;
		tr[pcnt].cnt++;
		rt=pcnt;
		pushup(rt);
		return;
	}
	ll cur=rt,f=0;
	while(1){
		if(tr[cur].val==x){
			tr[cur].cnt++;
			pushup(cur);
			pushup(f);
			splay(cur);
			return;
		}
		f=cur;
		cur=tr[cur].ch[tr[cur].val<x];
		if(!cur){
			tr[++pcnt].val=x;
			tr[pcnt].cnt++;
			fa[pcnt]=f;
			tr[f].ch[tr[f].val<x]=pcnt;
			pushup(pcnt);
			pushup(f);
			splay(pcnt);
			return;
		}
	}
}
inline ll grank(ll x){
	ll res=0,cur=rt;
	while(1){
	    if(tr[cur].val>x) cur=ls(cur);
	    else{
	        res+=tr[ls(cur)].sz;
	        if(tr[cur].val==x){
	            splay(cur);
	            return res+1;
	        }
	        res+=tr[cur].cnt;
	        cur=rs(cur);
	    }
	}
}
inline ll xth(ll x){
	ll cur=rt;
	while(1){
	    if(ls(cur)&&tr[ls(cur)].sz>=x) cur=ls(cur);
	    else{
	        x-=tr[ls(cur)].sz+tr[cur].cnt;
	        if(x<=0){
	            splay(cur);
	            return tr[cur].val;
	        }
	        cur=rs(cur);
	    }
	}
}
inline ll pre(){
	ll cur=ls(rt);
	if(!cur) return 0;
	while(rs(cur)) cur=rs(cur);
	splay(cur);
	return cur;
}
inline ll nxt(){
	ll cur=rs(rt);
	if(!cur) return 0;
	while(ls(cur)) cur=ls(cur);
	splay(cur);
	return cur;
}
inline void del(ll x){
	grank(x);
	if(tr[rt].cnt>1){
		tr[rt].cnt--;
		splay(rt);
		return;
	}
	if(!rs(rt)&&!ls(rt)){
		rt=0;
		return;
	}
	if(!ls(rt)||!rs(rt)){
		rt=ls(rt)+rs(rt);
		fa[rt]=0;
		return;
	}
	ll cur=rt;
	ll y=pre();
	fa[rs(cur)]=y;
	rs(y)=rs(cur);
	pushup(rt);
}
int main(){
    ll n;
	n=read();
	while(n--){
	    ll op,x;
		op=read(),x=read();
		if(op==1) ins(x);
		if(op==2) del(x);
		if(op==3) printf("%lld\n",grank(x));
		if(op==4) printf("%lld\n",xth(x));
		if(op==5) ins(x),printf("%lld\n",tr[pre()].val),del(x);
		if(op==6) ins(x),printf("%lld\n",tr[nxt()].val),del(x);
	}
	return 0;
}
2024/1/10 15:09
加载中...