题目传送门

题目描述
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
 

  分析:
  题目大意就是给你一个数列1,2,3,...n,然后有两种操作,一种是将一段区间取下来再接到另一个位置,另一种是区间反转。
  不难看出这是一道平衡树的题目,题目中的区间反转操作很明显的是Splay,用下放标记的方法很容易实现。再看另一种操作,要求将一段数列截下来然后放入另一段中,这个其实可以旋转以后把要移动的一段直接取下,然后在重新调整平衡树,记录要放入的区间的右端点,再把要放入的区间的左端点作为树根,把截下来的一段直接放上去,再调整,把右端点也接上去就可以了。具体看代码。
 
  Code:
  

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iomanip>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=3e5+;
int n,m,root,tot;
int cnt,ans[N];
struct Node{
int ch[],val,fa;
int size,mark;
void add(int x,int father){
mark=ch[]=ch[]=;
fa=father;val=x;size=;}
}t[N];
inline int read()
{
char ch=getchar();int num=;bool flag=false;
while(ch<''||ch>''){if(ch=='-')flag=true;ch=getchar();}
while(ch>=''&&ch<=''){num=num*+ch-'';ch=getchar();}
return flag?-num:num;
}
inline void pushup(int x)
{
int l=t[x].ch[],r=t[x].ch[];
t[x].size=t[l].size+t[r].size+;
}
inline void pushdown(int x)
{
if(t[x].mark){
t[t[x].ch[]].mark^=;
t[t[x].ch[]].mark^=;
swap(t[x].ch[],t[x].ch[]);
t[x].mark=;}
}
inline void rotate(int x)
{
int y=t[x].fa;
int z=t[y].fa;
int k=(t[y].ch[]==x);
t[z].ch[t[z].ch[]==y]=x;
t[x].fa=z;
t[y].ch[k]=t[x].ch[k^];
t[t[x].ch[k^]].fa=y;
t[x].ch[k^]=y;
t[y].fa=x;
pushup(y);pushup(x);
}
inline void splay(int x,int tag)
{
while(t[x].fa!=tag){
int y=t[x].fa;
int z=t[y].fa;
if(z!=tag)
(t[y].ch[]==x)^(t[z].ch[]==y)?
rotate(x):rotate(y);
rotate(x);}
if(tag==)root=x;
}
inline void insert(int x)
{
int now=root,fa=;
while(now)
fa=now,now=t[now].ch[x>t[now].val];
now=++tot;
if(fa)t[fa].ch[x>t[fa].val]=now;
t[now].add(x,fa);
splay(now,);
}
inline int find(int x)
{
int now=root;
while(){
pushdown(now);
if(t[t[now].ch[]].size>=x)now=t[now].ch[];
else if(t[t[now].ch[]].size+==x)return now;
else x-=(t[t[now].ch[]].size+),now=t[now].ch[];
}
}
inline int getmax(int x)
{
pushdown(x);
while(t[x].ch[]){
x=t[x].ch[];
pushdown(x);}
return x;
}
inline void merge(int x,int y)
{
t[x].ch[]=y;
t[y].fa=x;
}
inline void flip(int l,int r)
{
l=find(l),r=find(r+);
splay(l,);splay(r,l);
t[t[t[root].ch[]].ch[]].mark^=;
}
inline void cut(int x,int y,int z)
{
int l=find(x),r=find(y+);
splay(l,);splay(r,l);
int root1=t[t[root].ch[]].ch[];
t[t[root].ch[]].ch[]=;
pushup(t[root].ch[]);
pushup(root);
int neo=find(z+);
splay(neo,);
int root2=t[root].ch[];
merge(root,root1);
pushup(root);
int maxx=getmax(root);
splay(maxx,);
merge(root,root2);
pushup(root);
}
inline void travel(int now)
{
pushdown(now);
if(t[now].ch[])travel(t[now].ch[]);
if(t[now].val>&&t[now].val<n+)
ans[++cnt]=t[now].val-;
if(t[now].ch[])travel(t[now].ch[]);
}
int main()
{
while(){
n=read();m=read();
if(n<||m<)break;
root=tot=;
for(int i=;i<=n+;i++)
insert(i);
char opt[];int x,y,z;
for(int i=;i<=m;i++){
scanf("%s",opt);
if(opt[]=='F'){
x=read();y=read();
flip(x,y);}
else{
x=read();y=read();z=read();
cut(x,y,z);}
}
cnt=;
travel(root);
for(int i=;i<n;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[n]);
}
return ;
}

HDU3487 Play With Chain [Splay]的更多相关文章

  1. HDU--3487 Play with Chain (Splay伸展树)

    Play with Chain Problem Description YaoYao is fond of playing his chains. He has a chain containing ...

  2. HDU3487 Play with Chain splay 区间反转

    HDU3487 splay最核心的功能是将平衡树中的节点旋转到他的某个祖先的位置,并且维持平衡树的性质不变. 两个操作(数组实现) cut l,r, c把[l,r]剪下来放到剩下序列中第c个后面的位置 ...

  3. HDU-3487 Play with Chain Splay tee区间反转,移动

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3487 对于一个数列有两种操作:1.CUT a b c,先取出a-b区间的数,然后把它们放在取出后的第c ...

  4. HDU 3487 Play with Chain | Splay

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

  5. HDU3487 play with chain

    题目大意:给出1到n的有序数列,现在有两个操作: 1.CUT a b c 把第a到第b个数剪切下来,放到剩下的第c个数的后边. 2.FLIP a b  把第a到第b个数反转. 经过总共m次操作后,求现 ...

  6. HDU3487 Play With Chains(Splay)

    很裸的Splay,抄一下CLJ的模板当作复习,debug了一个下午,收获是终于搞懂了以前看这个模板里不懂的内容.以前用这个模板的时候没有看懂为什么get函数返回的前缀要加个引用,经过一下午的debug ...

  7. 【HDU 3487】Play with Chain Splay

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

  8. hdu3487Play with Chain(splay)

    链接 简单的两种操作,一种删除某段区间,加在第I个点的后面,另一个是翻转区间.都是splay的简单操作. 悲剧一:pushdown时候忘记让lz=0 悲剧二:删除区间,加在某点之后的时候忘记修改其父亲 ...

  9. 【HDU3487】【splay分裂合并】Play with Chain

    Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamonds on it ...

随机推荐

  1. 51Nod 1094 和为k的连续区间 | 水

    Input示例 6 10 1 2 3 4 5 6 Output示例 1 4 #include "cstdio" #include "algorithm" #in ...

  2. MyISAM和InnoDB的行格式ROW_FORMAT

    MyISAM行存储 MyISAM有3种行存储格式:fixed / dynamic / compressed: 格式 说明 备注   fixed  只有当表不包含变长字段(varchar/varbina ...

  3. codeforces contest 864 problemD

    Ivan has an array consisting of n elements. Each of the elements is an integer from 1 to n. Recently ...

  4. 今天安装了arch,感觉不错,这速度可以

    虽然没有想想中的那么那么快,不过已经可以了 总结一下遇到的问题以及i自己安装的软件 1.u盘硬盘不能自动挂载 安装gvfs 2.不能读写挂载 安装ntfs-3g 3.时间不对 照wiki上的说 #ln ...

  5. Unix/Linux Command Reference

  6. 【Windows使用笔记】Windows日常使用软件

    整理一些对于我来说日常使用的Windows软件. 排名不分先后,仅凭我想起来的顺序! 1 MadAppLauncher 这个对我来说非常需要了. 使用它可以快速启动日常常用的软件,非常快捷高效.一般来 ...

  7. redis线程安全性

    总体来说快速的原因如下: 1)绝大部分请求是纯粹的内存操作(非常快速) 2)采用单线程,避免了不必要的上下文切换和竞争条件 3)非阻塞IO 内部实现采用epoll,采用了epoll+自己实现的简单的事 ...

  8. 【模板】SPOJ FACT0 大数分解 miller-rabin & pollard-rho

    http://www.spoj.com/problems/FACT0/en/ 给一个小于1e15的数,将他分解. miller-rabin & pollard-rho模板 #include & ...

  9. C json实战引擎 三 , 最后实现部分辅助函数

    引言 大学读的是一个很时髦的专业, 学了四年的游戏竞技. 可惜没学好. 但认真过, 比做什么都认真. 见证了  ...... 打的所有游戏人物中 分享一位最喜爱 的 “I've been alone ...

  10. network-scoket

    server: using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...