luoguP6136 【模板】普通平衡树(数据加强版)

以前总是不愿意写平衡树,这次规范了一下写法.  

1. 建立虚拟节点 -inf 与 inf 

2. 每隔 10 次左右 splay 到根    

3. 各种操作写递归版就行.  

code: 

#include <cstdio> 
#include <algorithm> 
#include <cstring>   
#include <ctime>  

#define ll long long   
#define N 200007  
#define inf 2000000000     
#define setIO(s) freopen(s".in","r",stdin) 

using namespace std; 

int val[N],n,m,root;  

struct SPLAY_TREE {        

	#define lson s[x].ch[0] 
	#define rson s[x].ch[1] 
	struct data {
		int v,si,ch[2],f;  
	}s[N*10];    
	int tot;      
	inline int newnode () { return ++tot; }    
	inline int get(int x) { return s[s[x].f].ch[1]==x; }     
	inline void pushup(int x) { s[x].si=s[lson].si+s[rson].si+1; }

	inline void rotate(int x) 
	{
		int old=s[x].f,fold=s[old].f,which=get(x);  
		s[old].ch[which]=s[x].ch[which^1];   
		if(s[old].ch[which]) 
			s[s[old].ch[which]].f=old;   
		s[x].ch[which^1]=old,s[old].f=x,s[x].f=fold;   
		if(fold) 
			s[fold].ch[s[fold].ch[1]==old]=x;   
		pushup(old),pushup(x);   
	}    
	void splay(int x,int &tar) 
	{
		for(int u=s[tar].f,fa;(fa=s[x].f)!=u;rotate(x))  
			if(s[fa].f!=u)  
				rotate(get(fa)==get(x)?fa:x);    
		tar=x; 
	}
	void build(int l,int r,int &x) 
	{
		x=newnode();    
		int mid=(l+r)>>1;    
		s[x].v=val[mid];    
		if(mid>l)  build(l,mid-1,lson),s[lson].f=x;    
		if(r>mid)  build(mid+1,r,rson),s[rson].f=x;    
		pushup(x);   
	}
	void ins(int &x,int fa,int v) 
	{
		if(!x) x=newnode(),s[x].f=fa,s[x].v=v;    
		else ins(s[x].ch[v>s[x].v],x,v);   
		pushup(x);    
	}      
	int find(int x,int v) 
	{
		if(s[x].v==v) return x;  
		else return find(s[x].ch[v>s[x].v],v);    
	}   
	int getpre(int x,int v) 
	{       
		if(!x) return 0; 
		if(s[x].v<v) 
		{
			int a=x,b=getpre(rson,v); 
			return b==0?a:b;      
		}
		else return getpre(lson,v);    
	}
	int getaft(int x,int v) 
	{
		if(!x) return 0; 
		if(s[x].v>v) 
		{
			int a=x,b=getaft(lson,v);   
			return b==0?a:b;      
		} 
		else return getaft(rson,v);   
	}
	void del(int v) 
	{    
		int x=find(root,v),l,r; 
		splay(x,root),l=lson,r=rson;   
		while(s[l].ch[1]) l=s[l].ch[1];          
		splay(l,s[x].ch[0]);     
		s[r].f=l,s[l].f=0,s[l].ch[1]=r,pushup(l),root=l;    
	}         
	int getrank(int v) 
	{
		int x=getpre(root,v);                    
		splay(x,root);   
		return s[lson].si+1;             
	}       
	int getnum(int x,int kth) 
	{
		if(kth==s[lson].si+1) return x;  
		else if(kth<=s[lson].si) return getnum(lson,kth);  
		else return getnum(rson,kth-s[lson].si-1);   
	}
}bst;   

int main() 
{
	// setIO("input");    
	scanf("%d%d",&n,&m); 
	for(int i=1;i<=n;++i) scanf("%d",&val[i]); 
	sort(val+1,val+1+n);  
	val[0]=-inf,val[1+n]=inf;                     
	bst.build(0,1+n,root);            
	int lastans=0,op,x,y,ans=0;  
	for(int i=1;i<=m;++i) 
	{ 
		scanf("%d%d",&op,&x);  
		x^=lastans,y=0;               
		if(op==1) bst.ins(root,0,x),y=bst.tot;  
		if(op==2) bst.del(x);       
		if(op==3) lastans=bst.getrank(x),ans^=lastans;    
		if(op==4) y=bst.getnum(root,x+1),lastans=bst.s[y].v,ans^=lastans; 
		if(op==5) y=bst.getpre(root,x),lastans=bst.s[y].v,ans^=lastans; 
		if(op==6) y=bst.getaft(root,x),lastans=bst.s[y].v,ans^=lastans;    
		if(y&&(i%10==0)) bst.splay(y,root);   
	}      
	printf("%d\n",ans); 
	return 0; 
}

  

posted @ 2020-06-01 16:42  EM-LGH  阅读(216)  评论(0编辑  收藏  举报