【模板】Splay
文艺平衡树
注意到本题是按位置比较大小,val 值不满足二分查找性质,所以不存在 GetRank(Rt,val) 函数。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;
const int mx=5e5+5;
//Task : 文艺平衡树  
struct node{
	node *ch[2];
	node *fa;
	int key; //记录当前位置的数值 
	int siz;
	int lazy; //懒标记,记录是否交换左右儿子 
}tree[mx];
node *Root,*NIL,*ncnt;
int n,m;
void Init() {
	NIL=&tree[0];
	NIL->key=-INF;
	ncnt=&tree[1]; 
	Root=NIL->ch[0]=NIL->ch[1]=NIL->fa=NIL;
}
void PushUp(node *rt) {
	rt->siz=rt->ch[0]->siz+rt->ch[1]->siz+1;
}
void PushDown(node *rt) {
	if(rt==NIL) return;
	if(!rt->lazy) return;
	swap(rt->ch[0],rt->ch[1]);
	rt->ch[0]->lazy^=1;
	rt->ch[1]->lazy^=1;
	rt->lazy=0; 
}
void Rotate(node *x) {
	PushDown(x->fa);
	PushDown(x);
	//核心代码 
	//旋转之前先下传标记 
	node *y=x->fa;
	int d=(x==y->ch[0]);
	x->fa=y->fa;
	if(y->fa!=NIL) y->fa->ch[y->fa->ch[1]==y]=x;
	y->ch[!d]=x->ch[d];
	if(x->ch[d]!=NIL) x->ch[d]->fa=y;
	x->ch[d]=y;	
	y->fa=x;
	if(y==Root) Root=x;
	PushUp(y);
	PushUp(x); 
} 
node *NewNode(int val) {
	node *p=ncnt++;
	p->ch[0]=p->ch[1]=p->fa=NIL;
	p->key=val;
	p->siz=1;
	return p;
}
void Splay(node *x,node *rt) {
	node *y,*z;
	while(x->fa!=rt) {
		y=x->fa; z=y->fa;
		if(z==rt) {
			Rotate(x);
		}
		else {
			if((y==z->ch[0])^(x==y->ch[0])) 
			    Rotate(x);
			else 
			    Rotate(y);
			Rotate(x);
		}
	}
}
node *Select(node *rt,int k) {
	if(rt==NIL) return NIL; 
	PushDown(rt);
	if(k<=rt->ch[0]->siz) return Select(rt->ch[0],k);
	else if(k<=rt->ch[0]->siz+1) return rt;
	else return Select(rt->ch[1],k-rt->ch[0]->siz-1);
}
void Build(node *&rt,node *fa,int l,int r) {
	if(l>r) return;
	int mid=(l+r)>>1;
	rt=NewNode(mid);
	rt->fa=fa;
	Build(rt->ch[0],rt,l,mid-1);
	Build(rt->ch[1],rt,mid+1,r);
	PushUp(rt);
}
void Output(node *rt) {
	if(rt==NIL) return;
	PushDown(rt);
	Output(rt->ch[0]);
	if(rt->key>=1&&rt->key<=n) printf("%d ",rt->key);
	Output(rt->ch[1]);
}
void Reverse(int l,int r) {
	//1. l-1 提到根节点
	node *x=Select(Root,l),*y=Select(Root,r+2);
//	printf("YES");
	Splay(x,NIL),Splay(y,Root);
	Root->ch[1]->ch[0]->lazy^=1;
} 
int main() {
	scanf("%d%d",&n,&m); Init();
    Build(Root,NIL,0,n+1);
    while(m--) {
    	int l,r; scanf("%d%d",&l,&r);
    	Reverse(l,r);
	}
	Output(Root);
} 

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号