P3369(平衡树模板题)Treap未知原因51分,玄关求调
查看原帖
P3369(平衡树模板题)Treap未知原因51分,玄关求调
792502
Yaoyichen楼主2023/11/13 19:39

rt,参考 lyd老师 的紫书代码,有部分区别,但由于水平原因未能发现错误,自造数据没问题。

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define db double
#define inl inline
#define re register
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define F(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define DF(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define G(i,u) for(int (i)=head[u];(i);(i)=nxt[(i)])
inline ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}return x*f;}
//以上为头文件

const int SIZE=100005;
struct BST{
	int ls,rs,cnt,size;
	ll dat;
	ll val;
}t[SIZE];
int len,root;
void Update(int p){
	t[p].size=t[t[p].ls].size+t[t[p].rs].size+t[p].cnt;
	return ;
}
int NewN(ll val){
	t[++len].val=val;
	t[len].size=1;
	t[len].cnt=1;
	t[len].dat=rand();
	return len;
}
void BuildT(){
	NewN(-LINF);NewN(LINF);
	root=1;
	t[1].rs=2;t[0].ls=1;
	Update(1);
	return ;
}
int GetV(ll val,int p=root){
	if(p==0) return 0;
	if(t[p].val==val) return p;
	return t[p].val>val ? GetV(val,t[p].ls) : GetV(val,t[p].rs);
}
void zig(int &p){
	int q=t[p].ls;
	t[p].ls=t[q].rs; t[q].rs=p; p=q;
	Update(t[p].rs);
	Update(p);
	return ;
}
void zag(int &p){
	int q=t[p].rs;
	t[p].rs=t[q].ls; t[q].ls=p; p=q;
	Update(t[p].ls);
	Update(p);
	return ;
}
void InsertV(ll val,int &p){
	if(p==0){
		p=NewN(val);
		return;
	}
	if(val==t[p].val){
		t[p].cnt++;Update(p);
		return;
	}
	if(val<t[p].val){
		InsertV(val,t[p].ls);
		if(t[p].dat<t[t[p].ls].dat) zig(p);
	}
	else{
		InsertV(val,t[p].rs);
		if(t[p].dat<t[t[p].rs].dat) zag(p);
	}
	Update(p);
	return ;
}
ll NextN(ll val){
	int ans=2,p=root;
	while(p){
		if(t[p].val==val){
			if(t[p].rs>0){
				p=t[p].rs;
				while(t[p].ls>0) p=t[p].ls;
				ans=p;
			}
			break;
		}
		if(t[p].val>val && t[p].val<t[ans].val) ans=p;
		p= t[p].val>val ? t[p].ls : t[p].rs;
	}
	return t[ans].val;
}
ll PreN(ll val){
	int ans=1,p=root;
	while(p){
		if(t[p].val==val){
			if(t[p].ls>0){
				p=t[p].ls;
				while(t[p].rs>0) p=t[p].rs;
				ans=p;
			}
			break;
		}
		if(t[p].val<val && t[p].val>t[ans].val) ans=p;
		p= t[p].val>val ? t[p].ls : t[p].rs;
	}
	return t[ans].val;
}
void DeleteV(ll val,int &p){
	if(p==0) return;
	if(val==t[p].val){
		if(t[p].cnt>1){
			t[p].cnt--; Update(p); return;
		}
		else{
			if(t[p].ls || t[p].rs){
				if(t[p].rs==0 || t[t[p].ls].dat>t[t[p].rs].dat){
					zig(p);
					DeleteV(val,t[p].rs);
				}
				else{
					zag(p);
					DeleteV(val,t[p].ls);
				}
				Update(p);
			}
			else p=0;
			return;
		}
	}
	val<t[p].val ? DeleteV(val,t[p].ls) : DeleteV(val,t[p].rs);
	return;
}
int VtoR(ll val,int p){
	if(p==0) return 1;
	//cout<<p<<endl;
	if(val==t[p].val) return t[t[p].ls].size+1;
	if(val<t[p].val)  return VtoR(val,t[p].ls);
	return VtoR(val,t[p].rs)+t[t[p].ls].size+t[p].cnt; 
}
ll RtoV(ll rank,int p){
	rank++;
	if(p==0) return LINF;
	if(t[t[p].ls].size>=rank) return RtoV(rank-1,t[p].ls);
	if(t[t[p].ls].size+t[p].cnt>=rank)  return t[p].val;
	return RtoV(rank-1-t[t[p].ls].size-t[p].cnt,t[p].rs); 
}
ll n,opt,x;
int main(){
	BuildT();
	n=read();
	F(i,1,n){
		opt=read(),x=read();
		switch(opt){
			case 1:	InsertV(x,root); break;
			case 2:	DeleteV(x,root); break;
			case 3:	cout<<VtoR(x,root)-1<<endl; break;
			case 4:	cout<<RtoV(x,root)<<endl; break;
			case 5:	cout<<PreN(x)<<endl; break;
			case 6:	cout<<NextN(x)<<endl; break;
		}
		/*F(j,1,len){
			printf("%d %d %d %lld %lld %d %d\n",j,t[j].ls,t[j].rs,t[j].val,t[j].dat,t[j].cnt,t[j].size);
		}//调试代码*/
	}
	return 0;
}

2023/11/13 19:39
加载中...