文艺平衡树

和Splay差不多,就是维护区间,把siz值为l-1+1与r+1+1的两个节点,将一个旋转到根,另一个旋转到根的右儿子上,则要修改的区间就是根的右孩子的左子树,直接打标记即可。
推荐:远航之曲dalao

//Writer : Hsz %WJMZBMR%tourist%hzwer
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <cctype>
#include <vector>
#include <cstdlib>
#include <algorithm>
#define LL long long
#define M(a,b) memset(a,b,sizeof a)
using namespace std;
const int inf=0x3fffffff;
int in()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') {
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') {
		x=(x<<3)+(x<<1)+ch-'0';
		ch=getchar();
	}
	return x*f;
}
void out(int x)
{
	int a[25],wei=0;
	if(x<0) putchar('-'),x=-x;
	for(; x; x/=10) a[++wei]=x%10;
	if(wei==0) {
		puts("0");
		return;
	}
	for(int j=wei; j>=1; --j) putchar('0'+a[j]);
	putchar(' ');
}
const int N=500005;
int data[N],n,m;
struct Splay {
	int root,fa[N],ch[N][2],siz[N],rev[N],tot,key[N];
	void pushup(int x) {
		siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
		return;
	}
	bool check(int x) {
		return x==ch[fa[x]][1];
	}
	void pushdown(int x) {
		if(rev[x]&&x) {
			swap(ch[x][0],ch[x][1]);
			rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
			rev[x]=0;
		}
		return;
	}
	void rotate(int x) {
		int k=check(x),f=fa[x],ff=fa[f];
		pushdown(f);pushdown(x);
		ch[f][k]=ch[x][k^1];
		fa[ch[x][k^1]]=f;
		ch[x][k^1]=f;
		fa[f]=x;
		fa[x]=ff;
		if(ff) ch[ff][ch[ff][1]==f]=x;
		pushup(f);
		pushup(x);
	}
	void splay(int x,int tar) {
		for(int f; (f=fa[x])!=tar; rotate(x)) {
			if(fa[f]!=tar)rotate(check(x)==check(f)?f:x);
		}
		if(!tar) root=x;
	}
	int fnd(int k) {
		int now=root;
		while(1) {
			pushdown(now);
			if(k<=siz[ch[now][0]]) now=ch[now][0];
			else {
				k-=siz[ch[now][0]]+1;
				if(!k) return now;
				now=ch[now][1];
			}
		}
	}
	int build(int f,int l,int r) {
		if(l>r)return 0;
		int mid=(l+r)>>1;
		int now=++tot;
		key[now]=data[mid],fa[now]=f;
		ch[now][0]=build(now,l,mid-1);
		ch[now][1]=build(now,mid+1,r);
		pushup(now);
		return now;
	}
	void print(int x) {
		pushdown(x);
		if(ch[x][0]) print(ch[x][0]);
		if(key[x]!=-inf&&key[x]!=inf) out(key[x]);
		if(ch[x][1]) print(ch[x][1]);
	}
} SBT;

int main()
{
	n=in(),m=in();
	for(int i=1; i<=n; i++) data[i+1]=i;
	data[1]=-inf;
	data[n+2]=inf;
	SBT.root=SBT.build(0,1,n+2);
	for(int i=1,l,r; i<=m; i++) {
		l=in(),r=in();
		int x=SBT.fnd(l),y=SBT.fnd(r+2);
		SBT.splay(x,0);
		SBT.splay(y,x);
		SBT.rev[SBT.ch[SBT.ch[SBT.root][1]][0]]^=1;
	}
	SBT.print(SBT.root);
	return 0;
}
posted @ 2018-06-14 09:24  SWHsz  阅读(162)  评论(0编辑  收藏  举报