Description

瑶瑶很喜欢玩项链,她有一根项链上面有很多宝石,宝石从1到n编号。

首先,项链上的宝石的编号组成一个序列:1,2,3,...,n。

她喜欢两种操作:

1.CUT a b c:他会先将a至b号宝石切下来,然后接到c号宝石后面,组成一个新的项链。

举个例子,如果n=8,那么这个项链上的宝石编号依次为:1 2 3 4 5 6 7 8;'CUT 3 5 4',首先我们把3到5号宝石切下,项链变成了:1 2 6 7 8;然后接到4号宝石后面,此时的4号宝石为7,所以此时的项链变成了:1 2 6 7 3 4 5 8.

2.FLIP a b:像第一个操作一样我们先将a至b号宝石切下来,然后将其旋转180°,变成与原来相反的链,在插入到项链的相 同位置中。

举个例子,取操作1中的链:1 2 3 4 5 6 7 8,执行FLIP 2 6操作,则项链将变成:1 6 5 4 3 2 7 8.

他想知道经过m个操作之后项链会变成怎样。

Input

对于每一个数据,第一行会有两个整数:n m(1<=n,m<=300000) n代表宝石的个数,m代表操作的个数。

接下来有M行 有两个操作:

CUT A B C //代表CUT操作,1<=A<=B<=N, 0<=C<=N-(B-A+1).

FLIP A B //代表FLIP操作,1<=A<=B<=N.

输出的结尾将会有两个负数,他们不能当做操作.

Output

对于每一个数据,你需要输出N个整数,任两个数字间用一个空格分开,代表最终得到的项链的从1到N的宝石的序列号。

Sample Input

8 2

CUT 3 5 4

FLIP 2 6

-1 -1

Sample Output

1 4 3 7 6 2 5 8


splay区间操作请见浅谈算法——splay

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
inline void print(int x){
if (x>=10) print(x/10);
putchar(x%10+'0');
}
const int N=3e5;
int n,m;
struct Splay{
#define T(x) (tree[f[x]][1]==x)
int tree[N+10][2],f[N+10],size[N+10];
bool flag[N+10];
int root,cnt;
void clear(){
root=cnt=0;
memset(f,0,sizeof(f));
memset(tree,0,sizeof(tree));
memset(size,0,sizeof(size));
memset(flag,0,sizeof(flag));
}
void pushdown(int x){
if (!flag[x]) return;
swap(tree[x][0],tree[x][1]);
flag[tree[x][0]]^=1;
flag[tree[x][1]]^=1;
flag[x]=0;
}
void write(int x){
if (!x) return;
pushdown(x);
write(tree[x][0]);
if (x<=n) ++cnt!=n?printf("%d ",x):printf("%d\n",x);
write(tree[x][1]);
}
void build(){
root=n+1;
for (int i=1;i<=n;i++) f[i]=i+1,size[i]=i+1,tree[i+1][0]=i;
f[n+2]=1,size[n+2]=1,tree[1][0]=n+2;
size[root]=n+2;
}
void updata(int x){size[x]=size[tree[x][0]]+size[tree[x][1]]+1;}
void move(int x){
int fa=f[x],son=tree[x][T(x)^1];
tree[x][T(x)^1]=fa;
tree[fa][T(x)]=son;
if (son) f[son]=fa;
f[x]=f[fa];
if (f[x]) tree[f[x]][T(fa)]=x;
f[fa]=x;
updata(fa),updata(x);
}
void splay(int x){
while (f[x]){
if (f[f[x]]) T(x)==T(f[x])?move(f[x]):move(x);
move(x);
}
root=x;
}
int find(int x,int i){
if (!i) return 0;
pushdown(i);
if (size[tree[i][0]]+1==x) return i;
if (x<=size[tree[i][0]]) return find(x,tree[i][0]);
return find(x-size[tree[i][0]]-1,tree[i][1]);
}
void flip(){//区间翻转,打个标记即可
int x=read(),y=read();
x=find(x,root),splay(x);
y=find(y+2,root),splay(y);
if (f[x]!=root) move(x);
flag[tree[x][1]]^=1;
}
void consert(int x,int fa){//连边
if (tree[f[x]][T(x)]==x) tree[f[x]][T(x)]=0;
f[tree[fa][0]=x]=fa;
}
void up(int x){while (f[x]) updata(x),x=f[x];}//向上更新
void cut(){//区间切断
int x=read(),y=read(),z=read();
x=find(x+1,root),splay(x);
y=find(y+2,root),splay(y);
if (f[x]!=root) move(x);
consert(tree[x][0],f[x]);
z=find(z+2,root);
consert(tree[z][0],x);
consert(x,z);
up(x);
}
}T;
char s[10];
int main(){
while (1){
T.clear();
n=read(),m=read();
if (n==-1&&m==-1) break;
T.build();
for (int i=1;i<=m;i++){
scanf("%s",s);
if (s[0]=='F') T.flip();
if (s[0]=='C') T.cut();
}
T.write(T.root);
}
return 0;
}

Hdu 3487 play the chain的更多相关文章

  1. HDU 3487 Play with Chain(Splay)

    题目大意 给一个数列,初始时为 1, 2, 3, ..., n,现在有两种共 m 个操作 操作1. CUT a b c 表示把数列中第 a 个到第 b 个从原数列中删除得到一个新数列,并将它添加到新数 ...

  2. hdu 3487 Play with Chain

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3487 YaoYao is fond of playing his chains. He has a c ...

  3. HDU 3487 Play with Chain | Splay

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  4. HDU 3487 Play with Chain (splay tree)

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  5. HDU 3487 Play with Chain 【Splay】

    1-n的序列,有两种操作: 1,将一段区间翻转 2,将一段区间切下来放到剩余序列的第C个数后 采用延迟更新的方法维护区间的翻转,并维护一个size域. 添加一个最大点和一个最小点,防止出界 翻转时,将 ...

  6. 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 ...

  7. 【HDU 3487】Play with Chain Splay

    题意 给定$n$个数序列,每次两个操作,将区间$[L,R]$拼接到去掉区间后的第$c$个数后,或者翻转$[L,R]$ Splay区间操作模板,对于区间提取操作,将$L-1$ Splay到根,再将$R+ ...

  8. Play with Chain 【HDU - 3487】【Splay+TLE讲解】

    题目链接 很好的一道题,用了三天多的时间,终于知道了我为什么T的原因,也知道了在Splay的同时该怎样子的节约时间,因为Splay本身就是大常数的O(N*logN),我们如果不在各种细节上节约时间,很 ...

  9. 【HDU 5233】Tree chain problem (树形DP+树剖+线段树|树状数组)最大权不相交树链集

    [题目] Tree chain problem Problem Description Coco has a tree, whose vertices are conveniently labeled ...

随机推荐

  1. hdu 4091 数学思维题贪心

    /* 参看博客地址:http://blog.csdn.net/oceanlight/article/details/7857713 重点是取完最优的后剩余的rest=n%lcm+lcm;中性价比小的数 ...

  2. Python模块:logging、

    logging模块: 很多程序都有记录日志的需求,并且日志中包含的信息既有正常的程序访问日志,还可能有错误.警告等信息输出.Python的logging模块提供了标准的日志接口,你可以通过它存储各种格 ...

  3. 特种部队(codevs 1427)

    题目描述 Description 某特种部队接到一个任务,需要潜入一个仓库.该部队士兵分为两路,第一路士兵已经在正面牵制住了敌人,第二路士兵正在悄悄地从后方秘密潜入敌人的仓库.当他们到达仓库时候,发现 ...

  4. 【IntelliJ】IDEA使用--字体、编码和基本设置

    IDEA这么高端的工具之前只是断断续续使用了一下,因为项目的开发都是在eclipse上,每次学习IDEA的使用都得上网搜索半天,今天自己整理一下,方便以后查阅. IDEA版本15.0.4 字体 界面字 ...

  5. Linux下汇编语言学习笔记57 ---

    这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...

  6. n个点中求任意两点组成斜率的最大值

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1100 首先按x坐标排序,然后相邻的三个点A,B,C 组成的三条直线必然有 ...

  7. A Simple Problem with Integers-POJ3468

    Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...

  8. [Spring] Bean Scope Singleton cs Prototype

    We can define a class to be Singleton or Prototype. If the class was defined as Prototype, then ever ...

  9. 关于ping以及TTL的分析

    首先介绍一下ping这个工具 ping [目标] 的意思就是向目标发送几个数据包,之后假设目标接受到一个数据包.那么目标就会向发送ping的主机返回一个数据包 比方上图.我ping了百度的server ...

  10. HDU-3295-An interesting mobile game(BFS+DFS)

    Problem Description XQ,one of the three Sailormoon girls,is usually playing mobile games on the clas ...