平衡树板子

平衡树写法真的是太nm多了

首先是 \(Treap\) (当时比较sb于是写了指针

//#define LawrenceSivan

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
#define re register
#define INF 1<<30

struct node{
	ll key;
	int rank;
	int cnt;
	int size;
	
	node *son[2];
	
	bool operator < (const node &a)const{return rank<a.rank;}
	
	node(ll val):key(val),rank(rand()),cnt(1),size(1){
        son[0]=son[1]=NULL;
    }
	
	inline void update(){
		size=cnt;
		if(son[0]!=NULL)size+=son[0]->size;
		if(son[1]!=NULL)size+=son[1]->size;
	}
};

node *root;

inline void rotate(node* &o,int d){
	node *k=o->son[d^1];
	o->son[d^1]=k->son[d];
	k->son[d]=o;
	o->update();
	k->update();
	o=k;
}

void insert(node* &o,ll k){
	if(!o) o=new node(k);
	
	else if(o->key==k) o->cnt++;
	
	else{
		if(o->key>k)insert(o->son[0],k);
		else insert(o->son[1],k);
		
		if(o->son[0]&&(*o<*o->son[0]))rotate(o,1);
		else if(o->son[1]&&(*o<*o->son[1]))rotate(o,0);
	}
	
	o->update();
}

void remove(node* &o,ll k){
	if(o->key==k){
		if(o->cnt>1) o->cnt--;
		else{
			if(o->son[0]==NULL&&o->son[1]==NULL){
				delete o;
				o=NULL;
				return;
			}
			
			else if(o->son[0]&&o->son[1]){
				if(*o->son[0]<*o->son[1]){
					rotate(o,0);
					remove(o->son[0],k);
				}
				else{
					rotate(o,1);
					remove(o->son[1],k);
				}
			}
			
			else if(o->son[0]){
				rotate(o,1);
				remove(o->son[1],k);
			}
			
			else{
				rotate(o,0);
				remove(o->son[0],k);
			}
		}
	}
	
	else if(k<o->key)remove(o->son[0],k);
	
	else remove(o->son[1],k);
	
	o->update();
}

int kth(node* o,ll x){
	if(!o)return 1;
	
	int tmp= (o->son[0]?o->son[0]->size:0);
	
	if(o->key==x)return tmp+1;
	
	else if(x<o->key)return kth(o->son[0],x);
	
	else return tmp+o->cnt+kth(o->son[1],x);
}

ll find(node* o,int k){
	if(!o)return 0;
	
	int tmp= (o->son[0]?o->son[0]->size:0);
	
	if(tmp<k&&k<=tmp+o->cnt)return o->key;
	
	else if(k<=tmp)return find(o->son[0],k);
	
	else return find(o->son[1],k-tmp-o->cnt);
}

void pre(node* o,ll k,ll &ans){
	if(o==NULL)return;
	
	if(o->key<k){
		if(o->key>ans)ans=o->key;
		pre(o->son[1],k,ans);
	}
	
	else pre(o->son[0],k,ans);
}

void nxt(node* o,ll k,ll &ans){
	if(o==NULL)return;
	
	if(o->key>k){
		if(o->key<ans)ans=o->key;
		nxt(o->son[0],k,ans);
	}
	
	else nxt(o->son[1],k,ans);
}

ll n,T,op;

ll x,ans;

inline ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
    return x*f;
}

int main(){
#ifdef LawrenceSivan
    freopen("aa.in","r",stdin);
    freopen("aa.out","w",stdout);
#endif
	srand(time(0));
	T=read();
	
	while(T--){
		op=read();x=read();
		if(op==1)insert(root,x);
		if(op==2)remove(root,x);
		if(op==3){
			ans=kth(root,x);
			printf("%lld\n",ans);
		}
		if(op==4){
			ans=find(root,x);
			printf("%lld\n",ans);
		}
		if(op==5){
			ll anss=-INF;
			pre(root,x,anss);
			ans=anss;
			printf("%lld\n",ans);
		}
		if(op==6){
			ll anss=INF;
			nxt(root,x,anss);
			ans=anss;
			printf("%lld\n",ans);
		}
	}


	 return 0;
}


之后是 \(Splay\)

//#define LawrenceSivan

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
#define re register
const int maxn=1e5+5;
#define INF 0x7fffffff

#define ls(x) t[(x)].ch[0]
#define rs(x) t[(x)].ch[1]

int n,root,tot;

struct node{
	int ch[2];
	int fa;
	int cnt;//¸öÊý 
	int val;
	int son;//¶ù×ÓÊýÁ¿
}t[maxn]; 

inline void push_up(int x){
	t[x].son=t[ls(x)].son+t[rs(x)].son+t[x].cnt;
}

inline void rotate(int x){
	int f=t[x].fa;
	int g=t[f].fa;
	int s=rs(f)==x;
	
	t[g].ch[rs(g)==f]=x;t[x].fa=g;
	
	t[f].ch[s]=t[x].ch[s^1];t[t[x].ch[s^1]].fa=f;
	
	t[x].ch[s^1]=f;t[f].fa=x;
	
	push_up(f),push_up(x);
}

inline void Splay(int x,int goal){
	while(t[x].fa!=goal){
		int f=t[x].fa;
		int g=t[f].fa;
		if(g!=goal){
			(ls(f)==x)^(ls(g)==f)?rotate(x):rotate(f);
		}
		rotate(x);
	}
	
	if(goal==0){
		root=x;
	}
}

inline void insert(int x){
	int u=root,f=0;
	while(u&&t[u].val!=x){
		f=u;
		u=t[u].ch[x>t[u].val];
	}
	
	if(u) t[u].cnt++;
	
	else{
		u=++tot;
		if(f) t[f].ch[x>t[f].val]=u;
		
		ls(tot)=0;rs(tot)=0;
		t[tot].fa=f;
		t[tot].val=x;
		t[tot].cnt=1;
		t[tot].son=1;
	}
	Splay(u,0);
}

inline void find(int x){
	int u=root;
	if(!u)return;
	while(t[u].ch[x>t[u].val]&&x!=t[u].val){
		u=t[u].ch[x>t[u].val];
	}
	Splay(u,0);
}

inline int Nxt(int x,int f){
	find(x);
	
	int u=root;
	if((t[u].val>x&&f)||(t[u].val<x&&!f))return u;
	u=t[u].ch[f];
	
	while(t[u].ch[f^1])u=t[u].ch[f^1];
	
	return u;
}

inline void Delete(int x){
	int pre=Nxt(x,0);
	int nxt=Nxt(x,1);
	
	Splay(pre,0);Splay(nxt,pre);
	
	int del=ls(nxt);
	if(t[del].cnt>1){
		t[del].cnt--;
		Splay(del,0);
	}
	else ls(nxt)=0;
}

inline int kth(int x){
	int u=root;
	if(t[u].son<x)return 0;
	
	while(1){
		int s=ls(u);
		if(x>t[s].son+t[u].cnt){
			x-=t[s].son+t[u].cnt;
			u=rs(u);
		}
		else if(t[s].son>=x)u=s;
		
		else return t[u].val;
	}
}

inline int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
    return x*f;
}

int main(){
#ifdef LawrenceSivan
    freopen("aa.in","r",stdin);
    freopen("aa.out","w",stdout);
#endif
	n=read();
	
	insert(-INF);
    insert(INF);
    
    while(n--){
        int op=read();
        if(op==1){
        	int x=read();
			insert(x);
		}
        else if(op==2){
        	int x=read();
			Delete(x);
		}
        else if(op==3){
        	int x=read();
            find(x);
            printf("%d\n",t[ls(root)].son);
        }
    	else if(op==4){
    		int x=read();
    		printf("%d\n",kth(x+1));
		}
        else if(op==5){
        	int x=read();
        	printf("%d\n",t[Nxt(x,0)].val);
		}
        else if(op==6){
        	int x=read();
			printf("%d\n",t[Nxt(x,1)].val);
		}
    }
	
	
	return 0;
}

之后是替罪羊,

//#define LawrenceSivan

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
#define re register
const double alpha=0.7;
#define INF 0x3f3f3f3f

int n,op,x;

struct node{
	node *l,*r;
	
	int val,size,cnt;
	
	bool del;
	
	bool isbad(){
		return l->cnt>alpha*cnt||r->cnt>alpha*cnt;
	}
	
	void update(){
		size=!del+l->size+r->size;
		cnt=l->cnt+r->cnt+1;
	}
};

node *null,*root,**badtag;

void dfs(node* o,vector<node*> &v){
	if(o==null)return;
	
	dfs(o->l,v);
	if(!o->del)v.push_back(o);
	dfs(o->r,v);
	if(o->del)delete o;
}

node* build(vector<node*> &v,int l,int r){
	if(l>=r)return null;
	
	int mid=(l+r)>>1;
	node *o=v[mid];
	o->l=build(v,l,mid);
	o->r=build(v,mid+1,r);
	
	o->update();
	return o;
}

void rebuild(node* &o){
	vector<node*> v;
	dfs(o,v);
	o=build(v,0,v.size());
}

void Insert(node* &o,int x){
	if(o==null){
		o=new node;
		o->l=o->r=null;
		o->del=false;
		o->size=o->cnt=1;
		o->val=x;
		return;
	}
	
	else{
		o->size++;
		o->cnt++;
		if(x>=o->val)Insert(o->r,x);
		else Insert(o->l,x);
		
		if(o->isbad())badtag=&o;
		else if(badtag!=&null) o->cnt-=(*badtag)->cnt-(*badtag)->size;
	}
}

void insert(node* &o,int x){
	badtag=&null;
	Insert(o,x);
	if(badtag!=&null)rebuild(*badtag);
}

int Rank(node *o,int x){
	int ans=1;
	while(o!=null){
		if(o->val>=x)o=o->l;
		else{
			ans+=o->l->size+!o->del;
			o=o->r;
		}
	}
	return ans;
}

int kth(node *o,int x){
	while(o!=null){
		if(!o->del&&o->l->size+1==x)return o->val;
		
		if(o->l->size>=x)o=o->l;
		
		else{
			x-=o->l->size+!o->del;
			o=o->r;
		}
	}
}

void remove(node *o,int k){
	if(!o->del&&k==o->l->size+1){
		o->del=1;
		o->size--;
		return;
	}
	
	o->size--;
	if(k<=o->l->size+!o->del)remove(o->l,k);
	
	else remove(o->r,k-o->l->size-!o->del);
}

inline int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
    return x*f;
}

int main(){
#ifdef LawrenceSivan
    freopen("aa.in","r",stdin);
    freopen("aa.out","w",stdout);
#endif
	null=new node;
	root=null;
	
	n=read();
	while(n--){
		op=read();x=read();
		if(op==1)insert(root,x);
		if(op==2)remove(root,Rank(root,x));
		if(op==3)printf("%d\n",Rank(root,x));
		if(op==4)printf("%d\n",kth(root,x));
		if(op==5)printf("%d\n",kth(root,Rank(root,x)-1));
		if(op==6)printf("%d\n",kth(root,Rank(root,x+1)));
	}


	return 0;
}
posted @ 2021-05-28 21:57  LawrenceSivan  阅读(56)  评论(0编辑  收藏  举报