FHQ Treap#23pts
查看原帖
FHQ Treap#23pts
929819
HEIMOFA楼主2024/1/17 16:47
#include<bits/stdc++.h>
#define int long long
using namespace std;
int tot,rt=0;
const int N=1e5+5,INF=0x3f3f3f3f;
int ch[N][2],siz[N],sum[N],rk[N],dt[N];

void pushUp(int x){
	siz[x]=sum[x]+siz[ch[x][0]]+siz[ch[x][1]];
}
void Split(int now,int val,int &l,int &r){
	if(!now){
		l=r=0;
		return ;
	}
	if(dt[now]<=val){
		l=now,Split(ch[now][1],val,ch[now][1],r);
	}
	else{
		r=now,Split(ch[now][0],val,l,ch[now][0]);
	}
	pushUp(now);
}
int Merge(int &l,int &r){
	if(!l||!r) return l+r;
	if(rk[l]<rk[r]){
		ch[l][1]=Merge(ch[l][1],r);pushUp(l);
		return l;
	}
	else{
		ch[r][0]=Merge(ch[r][0],l);pushUp(r);
		return r;
	}
}
void Insert(int x){
	int t=rt;
	while(t){
		if(dt[t]==x){
			sum[t]++;
			t=rt;
			while(t){
				siz[t]++;
				if(dt[t]==x) return ;
				t=ch[t][x>dt[t]];
			}
		}
		t=ch[t][x>dt[t]];
	}
	rk[++tot]=rand(),dt[tot]=x;
	siz[tot]=sum[tot]=1;
	int l,r;
	Split(rt,x,l,r);
	l=Merge(l,tot),rt=Merge(l,r);
}
void Erase(int x){
	int t=rt;
	while(t){
		if(dt[t]==x&&sum[t]>0){
			sum[t]--;
			return ;
		}
		t=ch[t][x>dt[t]];
	}
	int l,r;
	Split(rt,x,l,r);
	rt=Merge(l,r);
}
int GetRankVal(int t,int x){
	//cout<<t<<" "<<dt[t]<<" "<<ch[t][0]<<" "<<ch[t][1]<<" "<<x<<endl;
	if(t==0) return 1;
	if(x==dt[t]) return siz[ch[t][0]]+1;
	if(x<dt[t]) return GetRankVal(ch[t][0],x);
	return GetRankVal(ch[t][1],x)+siz[ch[t][0]]+sum[t];
}
int GetValRank(int t,int x){
	if(t==0) return 1e9;
	if(siz[ch[t][0]]>=x) return GetValRank(ch[t][0],x);
	if(siz[ch[t][0]]+sum[t]>=x) return dt[t];
	return GetValRank(ch[t][1],x-siz[ch[t][0]]-sum[t]);
}
int GetPre(int x){
	int ans=-1e9;
	int t=rt;
	while(t){
		if(dt[t]<x) ans=dt[t],t=ch[t][1];
		else t=ch[t][0];
	}
	return ans;
}
int GetNext(int x){
	int ans=1e9;
	int t=rt;
	while(t){
		if(dt[t]<=x) t=ch[t][1];
		else ans=dt[t],t=ch[t][0];
	}
	return ans;
}
signed main()
{
	int n;scanf("%lld",&n);
	while(n--){
		int op,x;
		scanf("%lld%lld",&op,&x);
		if(op==1) Insert(x);
		if(op==2) Erase(x);
		if(op==3) printf("%lld\n",GetRankVal(rt,x));
		if(op==4) printf("%lld\n",GetValRank(rt,x));
		if(op==5) printf("%lld\n",GetPre(x));
		if(op==6) printf("%lld\n",GetNext(x));
	}
	return 0;
}

https://www.luogu.com.cn/record/143136448(提交记录)

2024/1/17 16:47
加载中...