求助平衡树P3369 WA58
  • 板块学术版
  • 楼主haozexu
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/11/16 16:08
  • 上次更新2023/11/18 11:20:49
查看原帖
求助平衡树P3369 WA58
555833
haozexu楼主2023/11/16 16:08

RT。发题目讨论区估计没人理,所以发这了。

P3369 提交记录 WA #7-12 58pts

用的是指针Splay,马蜂还是好认

使用一个null空节点,和两个哨兵-INF,INF

谢谢各位大佬

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int INF=INT_MAX;
#define AS_RSON 0
#define AS_LSON 1
namespace SplayContainer{
	class _;
	_ *null;
	class _{
	public:
		_ *ls,*rs,*fa;
		int siz,val,cnt;
		_(){
			ls=rs=fa=null;
			siz=val=cnt=0;
		}
		_(int v){
			ls=rs=fa=null;
			cnt=siz=1,val=v;
		}
		void Update(){
			this->siz=this->cnt;
			this->siz+=ls->siz,this->siz+=rs->siz;
		}
		void Bind(_ *son,bool as_lson=0){
//			printf("[Bind] Binding %d with %cson %d\n",this->val,as_lson?'l':'r',son->val);
			if(son==null){
				if(as_lson) this->ls=null;
				else		this->rs=null;
				this->Update();
				return;
			}
			son->fa=this;
			if(as_lson) this->ls=son;
			else		this->rs=son;
			this->Update();
		}
		bool Which(_ *obj){//Is lson
			return obj==ls;
		}
		_* Son(bool as_lson=0){
			return as_lson?this->ls:this->rs;
		}
	}*root;
	void Initalization(){
		null=new _;
		null->ls=null->rs=null->fa=null;
		root=null;
	}
}
using namespace SplayContainer;
void Recycle(_ *&p){
	if(p==null) return;
	Recycle(p->ls);
	Recycle(p->rs);
	delete p;
	p=null;
}
void Rotate(_ *p){
	_ *self=p,*father=p->fa,*grandfa=father->fa;
	bool loc1=father->Which(self);
//	printf("[Rotate] Rotating self%d,fa%d,grand%d\n",self->val,father->val,grandfa->val);
	if(father==root) root=self;
	father->Bind(self->Son(!loc1),loc1);
	self->Bind(father,!loc1);
	self->fa=null;
	if(grandfa!=null) grandfa->Bind(self,grandfa->Which(father));
}
void Splay(_ *x,_ *target=null){
	while(x->fa!=target){
		_ *fa=x->fa,*gfa=fa->fa;
//		printf("splay %d(which father is %d) into %d\n",x->val,x->fa->val,target->val);
		if(gfa!=target){
			if(gfa->Which(fa)==fa->Which(x)) Rotate(fa);
			else							 Rotate(x);
		}
		Rotate(x);
	}
	if(target==null) root=x;
}
_* Kth(_ * p,int k){
	if(p==null) return null;
	if(k<=p->ls->siz) return Kth(p->ls,k);
	else if(k>p->ls->siz+p->cnt) return Kth(p->rs,k-p->ls->siz-p->cnt);
	else return p;
}
int Rank(int k){
	int res=0;_ *cur=root;
	while(cur!=null){
		if(k<cur->val) cur=cur->ls;
		else{
			res+=cur->ls->siz;
			if(k==cur->val){
				Splay(cur);
				return res+1;
			}
			res+=cur->cnt;
			cur=cur->rs;
		}
	}
	return res+1;
}
_* Split(int l,int r){
	_ *pre=Kth(root,l-1),*nxt=Kth(root,r+1);
//	printf("[Split] [%d,%d]\n",l,r);
	Splay(pre,null),Splay(nxt,pre);
	return nxt;
}
void Insert(int x){
	int rnk=Rank(x);
	if(root->val==x){
		root->cnt++;
		return;
	}
//	printf("Knowing rnk is %d\n",rnk-1);
	rnk--; 
	_ *tar=Split(rnk+1,rnk);
	tar->Bind(new _(x),AS_LSON);
}
void Delete(int x){
	int rnk=Rank(x);
	if(root->cnt>1){
		root->cnt--;
		return;
	}
	_ *tar=Split(rnk,rnk);
	Recycle(tar->ls);
	tar->Update();
}
int Next(int x){
	Insert(x);
	int ans=Kth(root,Rank(x)+1)->val;
	Delete(x);
	return ans;
}
int Prev(int x){
	Insert(x);
	int ans=Kth(root,Rank(x)-1)->val;
	Delete(x);
	return ans;
}
void Init(){
	Initalization();
	root=new _(-INF);
	root->Bind(new _(INF),AS_RSON);
}
int main(){
	int n;cin>>n;
	Init();
	while(n--){
		int op,x;cin>>op>>x;
//		cout<<root->val<<endl;
		switch(op){
			case 1:{
				Insert(x);
				break;
			}
			case 2:{
				Delete(x);
				break;
			}
			case 3:{
				Insert(x);
				cout<<Rank(x)-1<<endl;
				Delete(x);
				break;
			}
			case 4:{
				cout<<Kth(root,x+1)->val<<endl;
				break;
			}
			case 5:{
				cout<<Prev(x)<<endl;
				break;
			}
			case 6:{
				cout<<Next(x)<<endl;
				break;
			}
		}
	}
	return 0;
}

2023/11/16 16:08
加载中...