【bzoj3223】Tyvj 1729 文艺平衡树

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


输入:

第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n 


输出:

输出一行n个数字,表示原始序列经过m次变换后的结果 


样例输入:
5 3
1 3
1 3
1 4


样例输出:

4 3 2 1 5


数据范围:

N,M<=100000



题解:

直接splay,打个rev标记就好了。

代码:

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

#ifdef WIN32
	#define LL "%I64d"
#else
	#define LL "%lld"
#endif

#ifdef CT
	#define debug(...) printf(__VA_ARGS__)
#else
	#define debug(...)
#endif

#define R register
#define getc() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
#define gmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define gmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1<<15],*S=B,*T=B;
inline int FastIn()
{
	R char ch;R int cnt=0;R bool minus=0;
	while (ch=getc(),(ch < '0' || ch > '9') && ch != '-') ;
	ch == '-' ?minus=1:cnt=ch-'0';
	while (ch=getc(),ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
	return minus?-cnt:cnt;
}
#define maxn 100010
bool rev[maxn];
int fa[maxn] , ch[maxn][2] , size[maxn] , root , n;
inline void update (R int x)
{
	R int ls = ch[x][0] , rs = ch[x][1];
	size[x] = size[ls] + size[rs] + 1;
}
void Build (R int l , R int r , R int rt)
{
	if (l > r) return ;
	R int mid = (l + r) >> 1;
	fa[mid] = rt;
	if (mid < rt) ch[rt][0] = mid;
	else ch[rt][1] = mid;
	Build(l , mid-1 , mid);
	Build(mid+1 , r , mid);
	update(mid);
}
inline void pushdown (R int x)
{
	R int ls = ch[x][0] , rs = ch[x][1];
	if (rev[x])
	{
		if (ls) rev[ls] ^= 1 ;
		if (rs) rev[rs] ^= 1 ;
		ch[x][0] = rs ; ch[x][1] = ls;
		rev[x] = 0;
	}
}
inline void rotate(R int x)
{
	R int f = fa[x] , gf = fa[f] , d = (ch[f][1] == x);
	if (f==root) root = x , ch [0][0] = x;
	(ch[f][d] = ch[x][d ^ 1]) >0 ? fa[ch[f][d]] = f : 0;
	(fa[x] = gf )> 0 ? ch[gf][ch[gf][1]==f] = x : 0;
	fa[ch[x][d^1] = f] = x;
	update (f);
}
inline void splay(R int x , R int rt)
{
	while (fa[x]!=rt)
	{
		R int f = fa[x] , gf = fa[f];
		if (gf != rt) rotate ( (ch[gf][1] == f) ^ (ch[f][1] == x) ? x : f );
		rotate (x);
	}
	update(x);
}
int find(R int x , R int rank)
{
	if (rev[x]) pushdown(x);
	R int ls = ch[x][0] , rs = ch[x][1] ,lsize = size[ls];
	if (lsize+1 == rank) return x;
	if (lsize >= rank ) return find(ls , rank);
	else return find(rs , rank -lsize -1);
}
inline int prepare (R int l,R int r)
{
	R int x = find (root ,l-1 );
	splay(x , 0);
	x = find(root , r+1) ;
	splay(x , root);
	return ch[x][0];
}
inline void rever(R int l,R int r)
{
	R int x = prepare (l,r);
	rev[x] ^= 1;
	pushdown(x);
}
inline void print(R int x)
{
	if (!x) return;
	if (rev[x]) pushdown(x);
	R int ls = ch[x][0] , rs = ch[x][1];
	print(ls);
	if (x != 1 && x!=n )printf("%d ",x -1 );
	print(rs);
}
int main()
{
	n = FastIn()+2 ;R int m = FastIn();
	Build(1 , n , 0);
	root = ( 1 + n ) >> 1;
	for (; m ; m--)
	{
		R int l = FastIn() + 1 , r = FastIn() + 1;
		rever( l , r );
	}
	splay(1,0);
	print(root);
	return 0;
}


 

posted @ 2016-03-09 17:26  cot  阅读(132)  评论(0编辑  收藏  举报