BZOJ3223 Tyvj 1729 文艺平衡树 splay

欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - BZOJ3223


题意概括

  您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 

  数据范围:n<=100000


题解

  splay裸题。

  加两个哨兵节点。

  还有pushdown标记


代码

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstdlib>
using namespace std;
const int N=100005;
int n,m;
struct Splay{
	int fa[N],son[N][2],rev[N],val[N],size[N],tot,root;
	void clear(){
		tot=root=0;
		memset(fa,0,sizeof fa);
		memset(son,0,sizeof son);
		memset(rev,0,sizeof rev);
	}
	void clear(int x,int v){
		val[x]=v;
		fa[x]=son[x][0]=son[x][1]=rev[x]=0;
		size[x]=1;
	}
	void pushup(int rt){
		int &ls=son[rt][0],&rs=son[rt][1];
		size[rt]=size[ls]+size[rs]+1;
	}
	void pushdown(int rt){
		int &ls=son[rt][0],&rs=son[rt][1];
		if (!rev[rt])
			return;
		rev[rt]=0;
		rev[ls]^=1;
		rev[rs]^=1;
		swap(ls,rs);
	}
	void rec_fa(int rt,int s,int p){
		son[rt][p]=s;
		fa[s]=rt;
	}
	int getp(int rt){
		return son[fa[rt]][1]==rt;
	}
	void rotate(int x){
		int y=fa[x],z=fa[y],p=getp(x);
		rec_fa(z,x,getp(y));
		rec_fa(y,son[x][!p],p);
		rec_fa(x,y,!p);
		pushup(y);
		pushup(x);
	}
	void down(int rt){
		if (fa[rt])
			down(fa[rt]);
		pushdown(rt);
	}
	void splay(int x,int anst){
		down(x);
		if (anst==0)
			root=x;
		for (int y=fa[x];fa[x]!=anst;rotate(x),y=fa[x])
			if (fa[y]!=anst)
				rotate(getp(x)==getp(y)?y:x);
	}
	int build(int L,int R){
		if (L>R)
			return 0;
		int rt=++tot,mid=(L+R)>>1;
		clear(rt,(1<=mid&&mid<=n)?mid:-1);
		int &ls=son[rt][0],&rs=son[rt][1];
		ls=build(L,mid-1);
		rs=build(mid+1,R);
		fa[ls]=fa[rs]=rt;
		pushup(rt);
		return rt;
	}
	int find(int x,int k){//find kth
		pushdown(x);
		int &ls=son[x][0],&rs=son[x][1];
		if (size[ls]+1==k)
			return x;
		if (size[ls]+1>k)
			return find(ls,k);
		if (size[ls]+1<k)
			return find(rs,k-size[ls]-1);
	}
	void answer(int rt){
		pushdown(rt);
		int &ls=son[rt][0],&rs=son[rt][1];
		if (ls)
			answer(ls);
		if (val[rt]!=-1)
			printf("%d ",val[rt]);
		if (rs)
			answer(rs);
	}
}s;
int main(){
	scanf("%d%d",&n,&m);
	s.clear();
	s.root=s.build(0,n+1);
	for (int i=1,L,R;i<=m;i++){
		scanf("%d%d",&L,&R);
		int x=s.find(s.root,L),y=s.find(s.root,R+2);
		s.splay(x,0);
		s.splay(y,x);
		s.rev[s.son[y][0]]^=1;
	}
	s.answer(s.root);
	return 0;
}
/*
5 3
1 3
1 3
1 4
*/

  

 

posted @ 2017-12-10 20:35  zzd233  阅读(213)  评论(0编辑  收藏  举报