【模板】带旋Treap(数组实现)

版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/82930887

参考题目:LOJ107


解析:

联赛完了统一更所有模板题解析。
指针实现看这里


代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const

inline
ll getint(){
	re ll num;
	re char c;
	while(!isdigit(c=gc()));num=c^48;
	while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
	return num;
}

inline
void outint(ll a){
	static char ch[23];
	if(a==0)pc('0');
	while(a)ch[++ch[0]]=a-a/10*10,a/=10;
	while(ch[0])pc(ch[ch[0]--]^48);
}

cs int N=300005;
struct TREAP{
	int lc[N],rc[N];
	int val[N];
	int p[N];
	int siz[N];
	int cnt[N];
	int tot,root;
	TREAP():tot(0),root(0){}
	
	void maintain(int k){
		siz[k]=siz[lc[k]]+siz[rc[k]]+cnt[k];
	}
	
	void Zig(int &k){
		int y=lc[k];
		lc[k]=rc[y];
		rc[y]=k;
		siz[y]=siz[k];
		maintain(k);
		k=y;
	}
	
	void Zag(int &k){
		int y=rc[k];
		rc[k]=lc[y];
		lc[y]=k;
		siz[y]=siz[k];
		maintain(k);
		k=y;
	}
	
	void insert(int &k,cs int &key){
		if(!k){
			k=++tot;
			lc[k]=rc[k]=0;
			val[k]=key;
			p[k]=rand();
			siz[k]=cnt[k]=1;
			return ;
		}
		++siz[k];
		if(val[k]==key)return (void)(++cnt[k]);
		if(val[k]<key){
			insert(rc[k],key);
			if(p[rc[k]]>p[k])Zag(k);
		}
		else{
			insert(lc[k],key);
			if(p[lc[k]]>p[k])Zig(k);
		}
	}
	void Insert(cs int &key){insert(root,key);}
	
	void del(int &k,cs int &key){
		if(!k)return;
		if(val[k]==key){
			if(cnt[k]>1)--cnt[k],--siz[k];
			else if(!lc[k]||!rc[k])k=lc[k]+rc[k];
			else if(p[lc[k]]<p[rc[k]])Zag(k),del(k,key);
			else Zig(k),del(k,key);
			return ;
		}
		--siz[k];
		if(key<val[k])del(lc[k],key);
		else del(rc[k],key);
	}
	void Delete(cs int &key){del(root,key);}
	
	int queryrank(cs int &key){
		int k=root,ans=0;
		while(k){
			if(val[k]==key)return ans+siz[lc[k]];
			if(key<val[k])k=lc[k];
			else ans+=siz[lc[k]]+cnt[k],k=rc[k];
		}
		return ans;
	}
	
	int querykth(int Rank){
		int k=root;
		while(k){
			if(siz[lc[k]]<Rank&&siz[lc[k]]+cnt[k]>=Rank)return val[k];
			if(siz[lc[k]]>=Rank)k=lc[k];
			else Rank-=siz[lc[k]]+cnt[k],k=rc[k];
		}
		return 0;
	}
	
	int querypre(cs int &k){
		int x=root,ans=-0x3f3f3f3f;
		while(x){
			if(val[x]>=k)x=lc[x];
			else ans=val[x],x=rc[x];
		}
		return ans;
	}
	
	int querysuf(cs int &k){
		int x=root,ans=0x3f3f3f3f;
		while(x){
			if(val[x]<=k)x=rc[x];
			else ans=val[x],x=lc[x];
		}
		return ans;
	}
	
}Treap;

int n;

signed main(){
	n=getint();
	while(n--){
		int op=getint(),x=getint();
		int ans;
		switch(op){
			case 0:Treap.Insert(x);break;
			case 1:Treap.Delete(x);break;
			case 2:outint(Treap.querykth(x)),pc('\n');break;
			case 3:outint(Treap.queryrank(x)),pc('\n');break;
			case 4:ans=Treap.querypre(x),(ans==-0x3f3f3f3f?puts("-1"):(outint(ans),pc('\n')));break;
			case 5:ans=Treap.querysuf(x),(ans==0x3f3f3f3f?puts("-1"):(outint(ans),pc('\n')));break;;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zxyoi_dreamer/article/details/82930887