HDU 3487(Play with Chain-Splay)[template:Splay]

Play with Chain

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 4679    Accepted Submission(s): 1892

Problem Description

YaoYao is fond of playing his chains. He has a chain containing n diamonds on it. Diamonds are numbered from 1 to n.

At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n.

He will perform two types of operations:

CUT a b c: He will first cut down the chain from the ath diamond to the bth diamond. And then insert it after the cth diamond on the remaining chain.

For example, if n=8, the chain is: 1 2 3 4 5 6 7 8; We perform “CUT 3 5 4”, Then we first cut down 3 4 5, and the remaining chain would be: 1 2 6 7 8. Then we insert “3 4 5” into the chain before 5th diamond, the chain turns out to be: 1 2 6 7 3 4 5 8.

FLIP a b: We first cut down the chain from the ath diamond to the bth diamond. Then reverse the chain and put them back to the original position.

For example, if we perform “FLIP 2 6” on the chain: 1 2 6 7 3 4 5 8. The chain will turn out to be: 1 4 3 7 6 2 5 8

He wants to know what the chain looks like after perform m operations. Could you help him?

Input

There will be multiple test cases in a test data.

For each test case, the first line contains two numbers: n and m (1≤n, m≤3*100000), indicating the total number of diamonds on the chain and the number of operations respectively.

Then m lines follow, each line contains one operation. The command is like this:

CUT a b c // Means a CUT operation, 1 ≤ a ≤ b ≤ n, 0≤ c ≤ n-(b-a+1).

FLIP a b    // Means a FLIP operation, 1 ≤ a < b ≤ n.

The input ends up with two negative numbers, which should not be processed as a case.

Output

For each test case, you should print a line with n numbers. The ith number is the number of the ith diamond on the chain.

Sample Input

8 2
CUT 3 5 4
FLIP 2 6
-1 -1

Sample Output

1 4 3 7 6 2 5 8

Source

2010 ACM-ICPC Multi-University Training Contest(5)——Host
by BJTU

Recommend

zhengfeng   |   We have carefully selected several similar problems for you:  3486 3479 3480 3481 3482

Splay    裸题

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define MAXN (300000+10)
#define MAXM (300000+10)
typedef long long ll;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}

int n,m;

class Splay
{
public:
	int father[MAXN],siz[MAXN],n;
	int ch[MAXN][2],val[MAXN];
	bool root[MAXN],rev[MAXN];
	int roo; //root
	void mem(int _n)
	{
		MEM(father) MEM(siz) MEM(root) MEM(rev)	MEM(ch) MEM(val) flag=0;
		n=0;
		roo=1;
		build(roo,1,_n,0);root[1]=1;
	}
	void newnode(int &x,int f,int v)
	{
		x=++n;
		father[x]=f;
		val[x]=v-1;
	}

	void build(int &x,int L,int R,int f)
	{
		if (L>R) return ;
		int m=(L+R)>>1;
		newnode(x,f,m);
		build(ch[x][0],L,m-1,x);
		build(ch[x][1],m+1,R,x);
		maintain(x);
	}
	int getkth(int x,int k)
	{
		pushdown(x);
		int t;
		if (ch[x][0]) t=siz[ch[x][0]]; else t=0;

		if (t==k-1) return x;
		else if (t>=k) return getkth(ch[x][0],k);
		else return getkth(ch[x][1],k-t-1);

	}

	void pushdown(int x)
	{
		if (x) if (rev[x])
		{
			swap(ch[x][0],ch[x][1]);
			if (ch[x][0]) rev[ ch[x][0] ]^=1;
			if (ch[x][1]) rev[ ch[x][1] ]^=1;
			rev[x]^=1;
		}
	}
	void maintain(int x)
	{
		siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
	}
	void rotate(int x)
	{
		int y=father[x],kind=ch[y][1]==x;

		pushdown(y); pushdown(x);

		ch[y][kind]=ch[x][!kind];
		if (ch[y][kind]) {
			father[ch[y][kind]]=y;
		}
		father[x]=father[y];
		father[y]=x;
		ch[x][!kind]=y;
		if (root[y])
		{
			root[x]=1;root[y]=0;roo=x;
		}
		else
		{
			ch[father[x]][ ch[father[x]][1]==y ] = x;
		}
		maintain(y);maintain(x);
	}
	void splay(int x)
	{
		while(!root[x])
		{
			int y=father[x];
			int z=father[y];
			if (root[y]) rotate(x);
			else if ( (ch[y][1]==x)^(ch[z][1]==y) )
			{
				rotate(x); rotate(x);
			}
			else
			{
				rotate(y); rotate(x);
			}
		}
		roo=x;
	}
	void splay(int x,int r)
	{
		while(!(father[x]==r))
		{
			int y=father[x];
			int z=father[y];
			if (father[y]==r) rotate(x);
			else if ( (ch[y][1]==x)^(ch[z][1]==y) )
			{
				rotate(x); rotate(x);
			}
			else
			{
				rotate(y); rotate(x);
			}
		}
	}

	void Cut(int a,int b,int c)
	{
		int x=getkth(roo,a),y=getkth(roo,b);
		splay(x);
		splay(y,roo);
		pushdown(x);pushdown(y);
		int z=ch[y][0];
		ch[y][0]=0; maintain(y); maintain(x);

		int u=getkth(roo,c),v=getkth(roo,c+1);
		splay(u);
		splay(v,roo);
		pushdown(u);pushdown(v);
		ch[v][0]=z;father[z]=v;
		maintain(v);maintain(u);

	}

	void Flip(int a,int b)
	{
		int x=getkth(roo,a),y=getkth(roo,b);
		splay(x);
		splay(y,roo);
		pushdown(x);pushdown(y);
		int z=ch[y][0];
		rev[z]^=1;
		maintain(y); maintain(x);
	} 

	bool flag;
	void print(int x)
	{
		if (x==0) return ;
		pushdown(x);
		print(ch[x][0]);

		if (val[x]!=0&&val[x]!=n-1)
		{
			if (flag) putchar(' '); else flag=1;
			printf("%d",val[x]);

		}
		print(ch[x][1]);
	} 

}S;
char s[MAXN];

int main()
{
//	freopen("hdu3487.in","r",stdin);
//	freopen(".out","w",stdout);

	while(cin>>n>>m)
	{
		if (n<0&&m<0) break;
		n+=2;
		S.mem(n);
		For(i,m)
		{
			scanf("%s",s);
			if (s[0]=='C')
			{
				int a,b,c;
				scanf("%d%d%d",&a,&b,&c);
				S.Cut(a,b+2,c+1);		

			} else {
				int a,b;
				scanf("%d%d",&a,&b);
				S.Flip(a,b+2);
			}
		}

		S.print(S.roo);cout<<endl;

	}

	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-06 22:57:37

HDU 3487(Play with Chain-Splay)[template:Splay]的相关文章

hdu 3487 Play with Chain(splay区间剪切,翻转)

题目链接:hdu 3487 Play with Chain 题意: cut a b c: 将a到b区间剪切下来,放在第c位置的后面. flip a b: 翻转a到b区间 题解: 第一个操作,选通过旋转,然后使a到b区间变成根的右儿子的左儿子,然后剪掉. 再找到c+1的位置,接上. 第二个操作,区间标记就行. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4

hdu 3487 Play with Chain (Splay)

hdu 3487 Splay树模板题 题意: 一开始给出1 2 3 4 ... n 这样一个序列,对这个序列进行以下两种操作: (1)CUT a b c: 将子串[a,b]切下来,放到剩余串的第c个数之后 . (2) FLIP a b : 将子串[a,b]翻转,如 1 2 3 4 就变成 4 3 2 1 . 总之就是一道Splay树的模板题 ... 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm&

hdu 3487 Play with Chain

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3487 YaoYao is fond of playing his chains. He has a chain containing n diamonds on it. Diamonds are numbered from 1 to n.At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n.He will perform t

Splay树——HDU 3487 Play with Chain

对应HDU题目:点击打开链接 Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4571    Accepted Submission(s): 1859 Problem Description YaoYao is fond of playing his chains. He has a chain cont

HDU 3487 Play with Chain 【Splay】

1-n的序列,有两种操作: 1,将一段区间翻转 2,将一段区间切下来放到剩余序列的第C个数后 采用延迟更新的方法维护区间的翻转,并维护一个size域. 添加一个最大点和一个最小点,防止出界 翻转时,将第L-1个点伸展到跟,再将第R+1个点伸展到L-1的右子树,这时R+1的左子树就是要翻转的区间,加上一个标记. 切区间时,跟翻转操作差不多,只是不加标记.然后找到C+1和C,将C伸展到根,C+1伸展到C的右子树,此时C+1的左子树就是要插入的位置. 其实我说了这么多并没有什么卵用....最后还是得自

POJ 3580(SuperMemo-Splay区间加)[template:Splay V2]

SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 11384   Accepted: 3572 Case Time Limit: 2000MS Description Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a memorizing game

HDOJ 3487 Play with Chain

前言 在编程过程中总结归纳出来的一种编程经验,从而形成的设计思想称为设计模式. 设计模式有23种.它适用于所有的编程语言. 常用的有创新型的设计模式:简单工厂.抽象工厂和单例模式:行为型的设计模式:模板设计模式.观察者模式和命令模式:结构性的设计模式:适配器设计模式.代理模式(静态和动态两种,典型的有在spring的AOP编程中使用)和装饰器设计模式. 正文 单例模式(singleton) 保证一个类在内存中只能创建一个实例. 1.实现步骤: 1)将构造器私有化,即使用private修饰构造器

HDU 3487:Play with Chain(Splay)

http://acm.hdu.edu.cn/showproblem.php?pid=3487 题意:有两种操作:1.Flip l r ,把 l 到 r 这段区间 reverse.2.Cut a b c ,把 a 到 b 这段区间切掉,再把这段区间接到切掉后的第 c 个数的后面. 思路:做完了上一道变态题目,做这道题目如鱼得水.Cut的时候就是把a 到 b 放到keytree的位置,记录一下当前keytree的值,然后切掉,再把切掉后的第 c 个数转到 root 的位置,再把这个记录的值重新连接回

【HDU 3487】Play with Chain Splay

题意 给定$n$个数序列,每次两个操作,将区间$[L,R]$拼接到去掉区间后的第$c$个数后,或者翻转$[L,R]$ Splay区间操作模板,对于区间提取操作,将$L-1$ Splay到根,再将$R+1$ Splay到根节点的右儿子,那么根节点右儿子的左儿子就对应区间$[L,R]$,对于反转操作,通过懒操作下放 代码 #include <bits/stdc++.h> #define inf 0x7f7f7f7f using namespace std; const int N = 500005