Play with Chain

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6779    Accepted Submission(s): 2678

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
题意:
有n个数1~n,两种操作,a b c表示将第a~b的数拿出来放到第c个数后面,a b表示翻转a~b之间的数
输出最终的数列
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define Key_Value ch[ch[root][1]][0]
const int maxn=;
int n,q;
int pre[maxn],ch[maxn][],rev[maxn],size[maxn],key[maxn],root,tot1;
void Update_Rev(int r){
if(r==) return;
swap(ch[r][],ch[r][]);
rev[r]^=;
}
void Push_Down(int r){
if(rev[r]){
Update_Rev(ch[r][]);
Update_Rev(ch[r][]);
rev[r]=;
}
}
void Push_Up(int r){
size[r]=+size[ch[r][]]+size[ch[r][]];
}
void New_Node(int &r,int fa,int k){
r=++tot1;
pre[r]=fa;
key[r]=k;
rev[r]=ch[r][]=ch[r][]=;
size[r]=;
}
void Build(int &x,int l,int r,int fa){
if(l>r) return;
int mid=(l+r)>>;
New_Node(x,fa,mid);
Build(ch[x][],l,mid-,x);
Build(ch[x][],mid+,r,x);
Push_Up(x);
}
void Init(){
root=tot1=;
key[root]=ch[root][]=ch[root][]=size[root]=rev[root]=pre[root]=;
New_Node(root,,-);
New_Node(ch[root][],root,-);
Build(Key_Value,,n,ch[root][]);
Push_Up(ch[root][]);
Push_Up(root);
}
void Rotate(int x,int kind){
int y=pre[x];
Push_Down(y);
Push_Down(x);
ch[y][!kind]=ch[x][kind];
pre[ch[x][kind]]=y;
if(pre[y]) ch[pre[y]][ch[pre[y]][]==y]=x;
pre[x]=pre[y];
ch[x][kind]=y;
pre[y]=x;
Push_Up(y);
}
void Splay(int r,int goal){
while(pre[r]!=goal){
if(pre[pre[r]]==goal)
Rotate(r,ch[pre[r]][]==r);
else{
int y=pre[r];
int kind=ch[pre[y]][]==y;
if(ch[y][kind]==r){
Rotate(r,!kind);
Rotate(r,kind);
}else{
Rotate(y,kind);
Rotate(r,kind);
}
}
}
Push_Up(r);
if(goal==) root=r;
}
int Get_Kth(int r,int k){
Push_Down(r);
int t=size[ch[r][]];
if(k==t+) return r;
else if(k<=t) return Get_Kth(ch[r][],k);
else return Get_Kth(ch[r][],k-t-);
}
void CUT(int a,int b,int c){
Splay(Get_Kth(root,a),);
Splay(Get_Kth(root,b+),root);
int temp=Key_Value;
Key_Value=;
Push_Up(ch[root][]);
Push_Up(root); Splay(Get_Kth(root,c+),);
Splay(Get_Kth(root,c+),root);
Key_Value=temp;
pre[Key_Value]=ch[root][];
Push_Up(ch[root][]);
Push_Up(root);
}
void REVERSE(int l,int r){
Splay(Get_Kth(root,l),);
Splay(Get_Kth(root,r+),root);
Update_Rev(Key_Value);
Push_Up(ch[root][]);
Push_Up(root);
}
int cnt;
void print(int r){
if(r==) return;
Push_Down(r);
print(ch[r][]);
if(cnt<n&&key[r]>){
cnt++;
printf("%d%c",key[r],cnt==n?'\n':' ');
}
print(ch[r][]);
}
int main()
{
while(scanf("%d%d",&n,&q)==){
if(n<&&q<) break;
Init();
char op[];
int x,y,z;
while(q--){
scanf("%s",op);
if(op[]=='C'){
scanf("%d%d%d",&x,&y,&z);
CUT(x,y,z);
}
else if(op[]=='F'){
scanf("%d%d",&x,&y);
REVERSE(x,y);
}
}
cnt=;
print(root);
}
return ;
}

HDU 3487 Splay tree的更多相关文章

  1. HDU 3487 Splay

    给定两种操作,一种是把一个数列的某一段切下来插到剩余数列的某一个位置上. 一种是翻转操作,把数列的某一段进行翻转. 都是Splay的基本操作.标准的Rotateto调整出 [a,b]区间.然后对[a, ...

  2. hdu 1754 splay tree伸展树 初战(单点更新,区间属性查询)

    题意:与区间查询点更新,点有20W个,询问区间的最大值.曾经用线段树,1000+ms,今天的伸展树,890没ms,差不多. 第一次学习伸展树,一共花了2个单位时间,感觉伸展树真很有用,也很好玩.现在只 ...

  3. HDU 3487 Play with Chain(Splay)

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

  4. HDU 4453 Looploop (伸展树splay tree)

    Looploop Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  5. HDU 1890 Robotic Sort (splay tree)

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  6. splay tree旋转操作 hdu 1890

    很神奇的旋转操作. 目前没看到其他数据结构能实现这个功能.平衡树不好处理区间操作,线段树很难旋转.splay tree搞这个就很简单了. 下面用的这个模板跑了700ms,好慢,估计是删除操作太费时了, ...

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

  8. HDU-3436 Queue-jumpers 树状数组 | Splay tree删除,移动

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3436 树状数组做法<猛戳> Splay tree的经典题目,有删除和移动操作.首先要离散化 ...

  9. HDU1890 Robotic Sort Splay tree反转,删除

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 题目中涉及数的反转和删除操作,需要用Splay tree来实现.首先对数列排序,得到每个数在数列 ...

随机推荐

  1. 「雅礼集训 2017 Day1」市场 (线段树除法,区间最小,区间查询)

    老师说,你们暴力求除法也整不了多少次就归一了,暴力就好了(应该只有log(n)次) 于是暴力啊暴力,结果我归天了. 好吧,在各种题解的摧残下,我终于出了一篇巨好看(chou lou)代码(很多结构体党 ...

  2. ajax 和 mock 数据

    ajax ajax是一种技术方案,但并不是一种新技术.它依赖的是现有的CSS/HTML/Javascript,而其中最核心的依赖是浏览器提供的XMLHttpRequest对象,是这个对象使得浏览器可以 ...

  3. codeforces 301D Yaroslav and Divisors(树状数组)

    Yaroslav has an array p = p1, p2, ..., pn (1 ≤ pi ≤ n), consisting of n distinct integers. Also, he ...

  4. Python中的相对导入语法

    Python中支持相对导入语法,即可以相对于某一个package进行导入,具体语法如下: # 导入"./dir2/spam.py", .表示当前目录 from .dir2 impo ...

  5. 自测之Lesson3:makefile

    题目:编写一个makefile文件,要求编译当前目录内的所有.c文件. 完成代码: .PHONY:clean all SRC=$(wildcard *.c) BIN=$(SRC:%.c=%) all: ...

  6. File Searching

    Description Have you ever used file searching tools provided by an operating system? For example, in ...

  7. “Hello World!”团队第三周召开的第一次会议

    今天是我们团队“Hello World!”团队第三周召开的第一次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.Todo List 六.会议照片 七.燃尽图 一.会议时间 ...

  8. Swift-可选值(Optional)讲解

    前提:Swift中有规定:对象中的任何属性在创建时,都必须要有明确的初始化值 1.定义可选类型 方式一:常规方式(不常用) var name : Optional<String> = ni ...

  9. Qt窗口及控件-QTreeview/QTableView排序问题

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt-QTreeview/QTableView排序问题     本文地址:http://tec ...

  10. Hadoop出现错误:WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable,解决方案

    安装Hadoop的时候直接用的bin版本,根据教程安装好之后运行的时候发现出现了:WARN util.NativeCodeLoader: Unable to load native-hadoop li ...