【模板】伸展树Splay区间操作(指针实现)

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

参考题目:LOJ105


解析:

联赛结束后统一更模板题题解。


代码:

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

inline
int getint(){
	re int 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(int 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 INF=0x3f3f3f3f;
typedef struct splay_node *point;
struct splay_node{
	point son[2],fa;
	int val,siz;
	bool tag;
	splay_node(int _val=0){
		son[0]=son[1]=NULL;
		fa=NULL;
		val=_val;
		siz=1;
		tag=0;
	}
	
	point &lc(){return son[0];}
	point &rc(){return son[1];}
	bool which(){return fa->rc()==this;}
	void update(){
		siz=(son[0]?son[0]->siz:0)+(son[1]?son[1]->siz:0)+1;
	}
	void init(){
		lc()=rc()=fa=NULL;
		siz=1;
		tag=0;
	}
	
	void pushdown(){
		if(tag){
			if(lc())
			lc()->tag^=1;
			if(rc())
			rc()->tag^=1;
			swap(lc(),rc());
			tag=0;
		}
	}
};

struct SPLAY{
	point root;
	SPLAY():root(NULL){}
	
	void Rotate(point now){
		point Fa=now->fa;
		Fa->pushdown();
		now->pushdown();
		bool pos=!now->which();
		Fa->son[!pos]=now->son[pos];
		if(now->son[pos])now->son[pos]->fa=Fa;
		if(now->fa=Fa->fa)now->fa->son[Fa->which()]=now;
		Fa->fa=now;
		now->son[pos]=Fa;
		Fa->update();
		now->update();
		if(now->fa==NULL)root=now; 
	}
	
	void Splay(point now,point to=NULL){
		for(point Fa;(Fa=now->fa)!=to;Rotate(now))
		if(Fa->fa!=to)Rotate((now->which()==Fa->which())?Fa:now);
	}
	
	point find(int key){
		point now=root;
		while(true){
			now->pushdown();
			if(now->lc()&&key<=now->lc()->siz){
				now=now->lc();
				continue;
			}
			key-=(now->lc()?now->lc()->siz:0)+1;
			if(key==0)return now;
			now=now->rc();
		}
	}
	
	void reverse(int x,int y){
		point l=find(x-1),r=find(y+1);
		Splay(l,NULL);
		Splay(r,l);
		point pos=root->rc();
		pos=pos->lc();
		pos->tag^=1;
	}
	
	void printinorder(point now){
		now->pushdown();
		if(now->lc())printinorder(now->lc());
		if(now->val!=INF)outint(now->val),pc(' ');
		if(now->rc())printinorder(now->rc());
	}
	
	void print(){
		printinorder(root);
	}
}splay;

int n,m;
point build(int l,int r){
	if(l>r)return NULL;
	int mid=(l+r)>>1;
	point now=(point)malloc(sizeof(splay_node));
	now->init();
	now->val=(mid==1||mid==n+2)?INF:(mid-1);
	now->son[0]=build(l,mid-1);
	now->son[1]=build(mid+1,r);
	if(now->son[0])now->son[0]->fa=now;
	if(now->son[1])now->son[1]->fa=now;
	now->update();
	return now;
}

signed main(){
	n=getint();
	m=getint();
	splay.root=build(1,n+2);
	while(m--){
		int l=getint();
		int r=getint();
		splay.reverse(l+1,r+1);
	}
	splay.print();
	return 0;
}

猜你喜欢

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