首页 > 代码库 > 【Splay】bzoj3223 Tyvj 1729 文艺平衡树

【Splay】bzoj3223 Tyvj 1729 文艺平衡树

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 100010
#define INF 2147483647
int fa[maxn],val[maxn],c[maxn][2],root,tot,siz[maxn],cnt[maxn],val2[maxn];
bool delta[maxn];
void Maintain(int x)
{
	siz[x]=siz[c[x][0]]+siz[c[x][1]]+cnt[x];
}
void Mark(int x){
	if(x){
		delta[x]^=1;
	}
}
void pushdown(int x){
	if(delta[x]){
		Mark(c[x][0]);
		Mark(c[x][1]);
		swap(c[x][0],c[x][1]);
		delta[x]=0;
		Maintain(x);
	}
}
void NewNode(int &x,int Fa,int key,int key2)
{
	x=++tot;
	fa[x]=Fa;
	c[x][0]=c[x][1]=0;
	val[x]=key;
	val2[x]=key2;
	siz[x]=cnt[x]=1;
}
void Rotate(int x,bool flag)
{
	int y=fa[x];
	pushdown(x);
	pushdown(y);
	c[y][!flag]=c[x][flag];
	fa[c[x][flag]]=y;
	if(fa[y]){
		c[fa[y]][c[fa[y]][1]==y]=x;
	}
	fa[x]=fa[y];
	c[x][flag]=y;
	fa[y]=x;
	Maintain(y);
}
void Splay(int x,int goal)
{
	if(!x || x==goal){
		return;
	}
	pushdown(x);
	int y;
	while((y=fa[x])!=goal){
		if(fa[y]==goal){
			Rotate(x,c[y][0]==x);
		}
		else{
			if((c[y][0]==x)==(c[fa[y]][0]==y)){
				Rotate(y,c[fa[y]][0]==y);
			}
		  	else{
				Rotate(x,c[y][0]==x);
				y=fa[x];
			}
			Rotate(x,c[y][0]==x);
		}
	}
	Maintain(x);
	if(!goal){
		root=x;
	}
}
int Find(int key,int x=root)
{
	while(c[x][val[x]<key]){
		if(val[x]==key){
			return x;
		}
		x=c[x][val[x]<key];
	}
	return x;
}
void Insert(int key,int key2)
{
	if(!root){
		NewNode(root,0,key,key2);
		return;
	}
	int x=Find(key);
	if(val[x]==key){
		++cnt[x];
		Splay(x,0);
		return;
	}
	NewNode(c[x][val[x]<key],x,key,key2);
	Splay(c[x][val[x]<key],0);
}
int Kth(int K,int x=root)
{
	while(1){
		pushdown(x);
		int Siz0=siz[c[x][0]];
		if(K<=Siz0){
			x=c[x][0];
		}
		else if(K<=Siz0+cnt[x]){
			break;
		}
		else{
			K-=(Siz0+cnt[x]);
			x=c[x][1];
		}
	}
	return x;
}
void print(int x)
{
	if(!x){
		return;
	}
	pushdown(x);
	print(c[x][0]);
	printf("%d ",val2[x]);
	print(c[x][1]);
	Maintain(x);
}
int n,m;
int main(){
	scanf("%d%d",&n,&m);
	Insert(0,0);
	for(int i=1;i<=n;++i){
		Insert(i,i);
	}
	Insert(n+1,n+1);
	int x,y;
	for(int i=1;i<=m;i++){
		scanf("%d%d",&x,&y);
		Splay(Kth(x),0);
		Splay(Kth(y+2),root);
		Mark(c[c[root][1]][0]);
	}
	Splay(Kth(1),0);
	Splay(Kth(n+2),root);
	print(c[c[root][1]][0]);
	return 0;
}

【Splay】bzoj3223 Tyvj 1729 文艺平衡树