1. 程式人生 > >【BZOJ5063】旅遊 Splay

【BZOJ5063】旅遊 Splay

ota class style sam getc pre build while 旅遊

【BZOJ5063】旅遊

Description

小奇成功打開了大科學家的電腦。 大科學家打算前往n處景點旅遊,他用一個序列來維護它們之間的順序。初 始時,序列為1,2,...,n。 接著,大科學家進行m次操作來打亂順序。每次操作有6步: 1、從序列開頭(左端)取出A個數(此時序列剩下n-A個數) 2、從序列開頭取出B個數 3、將第1步取出的A個數按原順序放回序列開頭 4、從序列開頭取出C個數 5、將第2步取出的B個數逆序放回序列開頭 6、將第4步取出的C個數按原順序放回序列開頭 你需要求出最終序列。

Input

第一行兩個數n,m。接下來m行,每行三個數A,B,C。 n,m<=100000

Output

輸出一行n個數表示最終序列。

Sample Input

10 2
6 2 2
5 3 6

Sample Output

1 2 8 7 3 9 6 5 4 10

題解:Splay裸題,但是不要全部按他告訴你的做。每次操作相當於將區間[A+1,A+B]挪到(C,C+1)中間。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=100010;
int n,m,rt,A,B,C;
struct node
{
	int ch[2],fa,siz,rev;
}s[maxn];
inline void pushup(int x)
{
	s[x].siz=s[s[x].ch[0]].siz+s[s[x].ch[1]].siz+1;
}
inline void pushdown(int x)
{
	if(s[x].rev)
	{
		swap(s[x].ch[0],s[x].ch[1]);
		if(s[x].ch[0])	s[s[x].ch[0]].rev^=1;
		if(s[x].ch[1])	s[s[x].ch[1]].rev^=1;
		s[x].rev=0;
	}
}
inline void rotate(int x,int &k)
{
	int y=s[x].fa,z=s[y].fa,d=(x==s[y].ch[1]);
	if(y==k)	k=x;
	else	s[z].ch[y==s[z].ch[1]]=x;
	s[x].fa=z,s[y].ch[d]=s[x].ch[d^1],s[y].fa=x;
	if(s[x].ch[d^1])	s[s[x].ch[d^1]].fa=y;
	s[x].ch[d^1]=y;
	pushup(y),pushup(x);
}
inline void splay(int x,int &k)
{
	while(x!=k)
	{
		int y=s[x].fa,z=s[y].fa;
		if(y!=k)
		{
			if((y==s[z].ch[0])^(x==s[y].ch[0]))	rotate(x,k);
			else	rotate(y,k);
		}
		rotate(x,k);
	}
}
int find(int x,int y)
{
	if(!x)	return 0;
	pushdown(x);
	if(y<=s[s[x].ch[0]].siz)	return find(s[x].ch[0],y);
	if(y>s[s[x].ch[0]].siz+1)	return find(s[x].ch[1],y-s[s[x].ch[0]].siz-1);
	return x;
}
int build(int l,int r,int last)
{
	if(l>r)	return 0;
	int x=(l+r)>>1;
	s[x].fa=last,s[x].siz=r-l+1;
	s[x].ch[0]=build(l,x-1,x);
	s[x].ch[1]=build(x+1,r,x);
	return x;
}
void dfs(int x)
{
	if(!x)	return ;
	pushdown(x);
	dfs(s[x].ch[0]);
	if(x>1&&x<n+2)	printf("%d ",x-1);
	dfs(s[x].ch[1]);
}
inline int rd()
{
	int ret=0,f=1;	char gc=getchar();
	while(gc<‘0‘||gc>‘9‘)	{if(gc==‘-‘)	f=-f;	gc=getchar();}
	while(gc>=‘0‘&&gc<=‘9‘)	ret=ret*10+gc-‘0‘,gc=getchar();
	return ret*f;
}
int main()
{
	n=rd(),m=rd();
	int i,x;
	rt=build(1,n+2,1);
	for(i=1;i<=m;i++)
	{
		A=rd(),B=rd(),C=rd();
		splay(find(rt,A+1),rt),splay(find(rt,A+B+2),s[rt].ch[1]);
		x=s[s[rt].ch[1]].ch[0],s[s[rt].ch[1]].ch[0]=0,pushup(s[rt].ch[1]),pushup(rt);
		s[x].rev^=1;
		splay(find(rt,C+1),rt),splay(find(rt,C+2),s[rt].ch[1]);
		s[s[rt].ch[1]].ch[0]=x,s[x].fa=s[rt].ch[1],pushup(s[rt].ch[1]),pushup(rt);
	}
	dfs(rt);
	return 0;
}

【BZOJ5063】旅遊 Splay