Play with Chain

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

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
 
Recommend
zhengfeng
 /* ***********************************************
Author :kuangbin
Created Time :2013/8/25 23:35:30
File Name :F:\2013ACM练习\专题学习\splay_tree_2\HDU3487.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std; #define Key_value ch[ch[root][1]][0]
const int MAXN = ;
int pre[MAXN],ch[MAXN][],root,tot1;
int key[MAXN],rev[MAXN];
int size[MAXN];
int s[MAXN],tot2;
int n,q; void NewNode(int &r,int father,int k)
{
if(tot2) r = s[tot2--];
else r = ++tot1;
key[r] = k;
pre[r] = father;
rev[r] = ;
ch[r][] = ch[r][] = ;
size[r] = ;
}
//反转的更新
void Update_Rev(int r)
{
if(!r) return;
swap(ch[r][],ch[r][]);
rev[r] ^= ;
}
void push_up(int r)
{
size[r] = size[ch[r][]] + size[ch[r][]] + ;
}
void push_down(int r)
{
if(rev[r])
{
Update_Rev(ch[r][]);
Update_Rev(ch[r][]);
rev[r] = ;
}
} void Build(int &x,int l,int r,int father)
{
if(l > r)return;
int mid = (l+r)/;
NewNode(x,father,mid);
Build(ch[x][],l,mid-,x);
Build(ch[x][],mid+,r,x);
push_up(x);
}
void Init()
{
root = tot1 = tot2 = ;
ch[root][] = ch[root][] = size[root] = key[root] = pre[root] = rev[root] = ;
NewNode(root,,-);
NewNode(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)
{
push_down(r);
while(pre[r] != goal)
{
if(pre[pre[r]] == goal)
{
push_down(pre[r]);
push_down(r);
Rotate(r,ch[pre[r]][]==r);
}
else
{
push_down(pre[pre[r]]);
push_down(pre[r]);
push_down(r);
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(t == k)return r;
if(t > k)return Get_kth(ch[r][],k);
else return Get_kth(ch[r][],k-t);
}
//将[l,r]段剪切下来,放在剩下段的第c个后面
void CUT(int l,int r,int c)
{
Splay(Get_kth(root,l),);
Splay(Get_kth(root,r+),root);
int tmp = Key_value;
Key_value = ;
push_up(ch[root][]);
push_up(root);
Splay(Get_kth(root,c+),);
Splay(Get_kth(root,c+),root);
Key_value = tmp;
pre[Key_value] = ch[root][];
push_up(ch[root][]);
push_up(root);
}
//将[l,r]段反转
void FLIP(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 InOrder(int r)
{
if(!r)return;
push_down(r);
InOrder(ch[r][]);
if(cnt >= && cnt <= n)
{
printf("%d",key[r]);
if(cnt < n)printf(" ");
else printf("\n");
}
cnt++;
InOrder(ch[r][]);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
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
{
scanf("%d%d",&x,&y);
FLIP(x,y);
}
}
cnt = ;
InOrder(root);
}
return ;
}

HDU 3487 Play with Chain (splay tree)的更多相关文章

  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 【Splay】

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

  3. HDU 3478 Play with Chain (Splay树)

    这种高级数据结构太难搞了.........现在还是先照着别人的代码敲,做模板..........慢慢花时间来弄懂 #include <iostream> #include <algo ...

  4. 伸展树(Splay Tree)进阶 - 从原理到实现

    目录 1 简介 2 基础操作 2.1 旋转 2.2 伸展操作 3 常规操作 3.1 插入操作 3.2 删除操作 3.3 查找操作 3.4 查找某数的排名.查找某排名的数 3.4.1 查找某数的排名 3 ...

  5. 数据结构(二) --- 伸展树(Splay Tree)

    文章图片和代码来自邓俊辉老师课件 概述 伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由丹尼尔·斯立特Daniel Sleator ...

  6. HDU 1890 Robotic Sort (splay tree)

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

  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. 纸上谈兵:伸展树(splay tree)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们讨论过,树的搜索效率与树的深度有关.二叉搜索树的深度可能为n,这种情况下,每次 ...

  9. bzoj1251 序列终结者(Splay Tree+懒惰标记)

    Description 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这 ...

随机推荐

  1. MyEclipse中点击Deploy MyEclipse J2EE Project to Server无响应解决方法

    问题: MyEclipse中点击Deploy MyEclipse J2EE Project to Server无响应 解决方法: 如果工作空间的问题,那么需要删除你工作空间的一个文件就可以解决了.这个 ...

  2. PHP获得用户的真实IP地址

    <?php /** * 获得用户的真实IP地址 * * @access public * @return string */ function real_ip() { static $reali ...

  3. 缓存数据库-redis数据类型和操作(hash)

    一:Redis 哈希(Hash) Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象. Redis 中每个 hash 可以存储 232 - 1 ...

  4. Selenium_多线程执行测试用例

    多线程执行测试用例 这里以百度搜索为例,通过不同的浏览器来启动不同的线程. #!/usr/bin/env python # _*_ coding:utf-8 _*_ __author__ = 'Yin ...

  5. T-sql语句修改数据库逻辑名、数据库名、物理名(sql2000)

    --更改MSSQL数据库物理文件名Sql语句的写法 --注意:要在活动监视器里面确保没有进程连接你要改名的数据库!!!!!!!!!!!!!!!!!!!! -- Sql语句如下 USE master - ...

  6. Master和worker模式

    让和hadoop的设计思想是一样的,Master负责分配任务和获取任务的结果,worker是真正处理业务逻辑的. 使用ConcurrentLikedQueue去承载所有的任务,因为会有多个worker ...

  7. MATLAB读写Excel文件中的数据

    读取: %读取filename文件中指定表的数据,存入dataRead矩阵中 dataRead=xlsread('filename.xls',sheet); 写入: %将矩阵dataWrite中的数据 ...

  8. jquery获取浏览器宽高

    满足获取各种高的需求 $(document).ready(function() { alert($(window).height()); //浏览器时下窗口可视区域高度 alert($(documen ...

  9. 【LOJ】#2290. 「THUWC 2017」随机二分图

    题解 看了一眼觉得是求出图对图统计完美匹配的个数(可能之前做过这样模拟题弃疗了,一直心怀恐惧... 然后说是统计一下每种匹配出现的概率,也就是,当前左边点匹配状态为S,右边点匹配状态为T,每种匹配出现 ...

  10. Python 多线程 实例

    多线程实例 import threading import time def eat(): eatTime = time.time() for i in range(30): print('count ...