Treap平衡树58pts求调
查看原帖
Treap平衡树58pts求调
933802
ICU152_lowa_IS8楼主2024/8/2 16:27
#include<bits/stdc++.h>
#define int long long
using namespace std;
int ch[1000005][2];
int cnt[1000005],dat[1000005],val[1000005];
int siz[1000005];
int tot,root;
inline int New(int v){
	val[++tot]=v;
	cnt[tot]=1;
	siz[tot]=1;
	dat[tot]=rand();
//	cout<<tot<<endl;
	return tot;
}
inline void pushup(int p){
	siz[p]=siz[ch[p][1]]+siz[ch[p][0]]+cnt[p];
}
inline void build(){
	root=New(-0x3f3f3f3f3f3f3f3f);
//	cout<<"ASDJLK\n";
	ch[root][1]=New(0x3f3f3f3f3f3f3f3f);
	pushup(root);
}
inline void Rotate(int &id,int d){
	int temp=ch[id][d^1];
	ch[id][d^1]=ch[temp][d];
	ch[temp][d]=id;
	id=temp;
	pushup(ch[id][d]);
	pushup(id);
}
inline void insert(int &id,int v){
	if(!id){
		id=New(v);
		return;
	}
	if(v==val[id]){
		cnt[id]++;
		return;
	}
	else{
		int d=v<val[id]?0:1;
		insert(ch[id][d],v);
		if(dat[id]<dat[ch[id][d]])Rotate(id,d^1);
	}
	pushup(id);
}
inline void del(int &id,int v){
	if(!id)return;
	if(v==val[id]){
		if(cnt[v]>1)cnt[v]--;
		else if(ch[id][1]||ch[id][0]){
			if(!ch[id][1]||dat[ch[id][0]]>dat[ch[id][1]]){
				Rotate(id,1);
				del(ch[id][1],v);
			}
			else{
				Rotate(id,0);
				del(ch[id][0],v);
			}
		}
		else{
			id=0;
		}
		return;
	}
	else{
		int d=v<val[id]?0:1;
		del(ch[id][d],v);
	}
	pushup(id);
}
inline int getrank(int id,int v){
	if(!id)return 1;
	if(v==val[id]){
		return siz[ch[id][0]]+1;
	}
	else if(v<val[id]){
		return getrank(ch[id][0],v);
	}
	else{
		return getrank(ch[id][1],v)+siz[ch[id][0]]+cnt[id];
	}
}
inline int getnum(int id,int rank){
	if(!id)return 0x3f3f3f3f3f3f3f3f;
	if(rank<=siz[ch[id][0]]){
		return getnum(ch[id][0],rank);
	}
	else if(rank<=siz[ch[id][0]]+cnt[id]){
		return val[id];
	}
	else{
		return getnum(ch[id][1],rank-siz[ch[id][0]]-cnt[id]);
	}
}
inline int getpre(int v){
	int id=root,pre;
	while(id){
		if(val[id]<v){
			pre=val[id];
			id=ch[id][1];
		}
		else{
			id=ch[id][0];
		}
	}
	return pre;
}
inline int getnext(int v){
	int id=root,next;
	while(id){
		if(val[id]>v){
			next=val[id];
			id=ch[id][0];
		}
		else{
			id=ch[id][1];
		}
	}
	return next;
}
signed main(){
	freopen("P3369_8.in","r",stdin);
	freopen("test.out","w",stdout);
	srand(time(NULL));
	int n;
	cin>>n;
	build();
	while(n--){
		int op,x;
		cin>>op>>x;
		if(op==1)insert(root,x);
		else if(op==2)del(root,x);
		else if(op==3)cout<<getrank(root,x)-1<<"\n";
		else if(op==4)cout<<getnum(root,x+1)<<"\n";
		else if(op==5)cout<<getpre(x)<<"\n";
		else cout<<getnext(x)<<"\n";
	}
	return 0;
}

2024/8/2 16:27
加载中...