Play with Chain

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

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

 
 

分析

splay功能,区间旋转,区间截取及插入。

区间截取及插入

1、截取区间[a, b]

把第a-1个数旋转到根,把第b+1个数旋转到根的右儿子,那么b+1的左儿子就是所要截取的区间,把b的左儿子记录下即可,更新。

2、插入一段区间到第c个数后

把第c个数旋转到根,把第c+1个数旋转到根的右儿子,那么b+1的左儿子一定是空的,然后将要插入的区间的根节点赋值给b的左儿子即可,更新。

区间翻转:

翻转区间[a, b]

把第a-1个数旋转到根,把第b+1个数旋转到根的右儿子,那么b+1的左儿子就是所要截取的区间,打个标记即可,用到了再下传。

code

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream> using namespace std; const int N = ; int ch[N][],fa[N],tag[N],siz[N],data[N];
int Root,n,m,cnt; inline int read() {
int x = ,f = ;char ch = getchar();
for (; ch<''||ch>''; ch = getchar()) if (ch=='-') f = -;
for (; ch>=''&&ch<=''; ch = getchar()) x = x * + ch - '';
return x * f;
}
inline void pushup(int x) {
siz[x] = siz[ch[x][]] + siz[ch[x][]] + ;
}
inline void pushdown(int x) {
if (tag[x]) {
tag[ch[x][]] ^= ;tag[ch[x][]] ^= ;
swap(ch[x][],ch[x][]);
tag[x] ^= ;
}
}
inline int son(int x) {
return x == ch[fa[x]][];
}
inline void rotate(int x) {
int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
if (z) ch[z][c] = x;else Root = x;fa[x] = z;
ch[x][!b] = y;fa[y] = x;
ch[y][b] = a;if (a) fa[a] = y;
pushup(y);pushup(x);
}
inline void splay(int x,int rt) {
while (fa[x] != rt) {
int y = fa[x],z = fa[y];
if (z==rt) rotate(x);
else {
if (son(x) == son(y)) rotate(y),rotate(x);
else rotate(x),rotate(x);
}
}
}
inline int getkth(int k) {
int p = Root;
while (true) {
pushdown(p);
if (siz[ch[p][]] + == k) return p;
if (ch[p][] && k <= siz[ch[p][]] ) p = ch[p][];
else {
k -= ((ch[p][] ? siz[ch[p][]] : ) + );
p = ch[p][];
}
}
}
inline void rever(int l,int r) {
int L = getkth(l),R = getkth(r + );
splay(L,);splay(R,L);
tag[ch[R][]] ^= ;
}
inline void cut(int l,int r,int p) {
int L = getkth(l),R = getkth(r+);
splay(L,);splay(R,L);
int tmp = ch[R][];
fa[tmp] = ;ch[R][] = ;
pushup(R);pushup(L);
L = getkth(p+),R = getkth(p+);
splay(L,);splay(R,L);
fa[tmp] = R;ch[R][] = tmp;
pushup(R);pushup(L);
}
int build(int l,int r) {
if (l > r) return ;
int mid = (l + r) >> ;
int t = build(l,mid-);
ch[mid][] = t;fa[t] = mid;
t = build(mid+,r);
ch[mid][] = t;fa[t] = mid;
pushup(mid);
return mid;
}
void print(int x) {
if (!x) return ;
pushdown(x);
print(ch[x][]);
if (data[x] > && data[x] < n+) {
if (cnt==) printf("%d",data[x]),cnt = ;
else printf(" %d",data[x]);
}
print(ch[x][]);
}
inline void init() {
Root = cnt = ;
memset(ch,,sizeof(ch));
memset(fa,,sizeof(fa));
memset(tag,,sizeof(tag));
memset(siz,,sizeof(siz));
memset(data,,sizeof(data));
}
int main() {
int a,b,c;
char s[];
while (scanf("%d%d",&n,&m)!=EOF && !(n==-&&m==-)) {
init();
for (int i=; i<=n+; ++i) data[i] = i-;
Root = build(,n+);
while (m--) {
scanf("%s",s);
if (s[]=='C') {
a = read(),b = read(),c = read();
cut(a,b,c);
}
else {
a = read(),b = read();
rever(a,b);
}
}
print(Root);
printf("\n");
}
return ;
}

hdu3487Play with Chain的更多相关文章

  1. Hdu3487-Play with Chain(伸展树分裂合并)

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

  2. hdu3487Play with Chain(splay)

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

  3. STM32用JLINK 烧写程序时出现NO Cortex-m device found in JTAG chain现象和解决方案

    现象 CPU: STM32107VC 用JLINK 烧写程序时出现NO Cortex-m device found in JTAG chain 如图无法查找到硬件就是CPU 提示1:NO Cortex ...

  4. 责任链模式/chain of responsibility/行为型模式

    职责链模式 chain of responsibility 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处 ...

  5. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  6. arm,iptables: No chain/target/match by that name.

    最近由于项目需要,需要打开防火墙功能. 公司有 arm linux 3.0x86 linux 3.2x86 linux 2.4 的三个嵌入式.都需要打开防火墙功能. 执行“whereis iptabl ...

  7. C#设计模式系列:职责链模式(Chain of Responsibility)

    1.职责链模式简介 1.1>.定义 职责链模式是一种行为模式,为解除请求的发送者和接收者之间的耦合,而使多个对象都有机会处理这个请求.将这些对象连接成一条链,并沿着这条链传递该请求,直到有一个对 ...

  8. [工作中的设计模式]责任链模式chain

    一.模式解析 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知 ...

  9. track message forwards, avoiding request loops, and identifying the protocol capabilities of all senders along the request/response chain

    https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html The TRACE method is used to invoke a remote, ...

随机推荐

  1. Control中的AOP实现非业务需求

    一.能够使用Control中的AOP实现非业务需求的功能 本文目录 一.ActionFilterAttribute类 二.实现自定义Attribute 一.ActionFilterAttribute类 ...

  2. C#字符串变量使用

    string由于是引用类型,所以,声明的字符串变量会存储到堆上,而且该变量是不可变的,一旦初始化了该变量,该内存区域中存储的内容将不能更改.在对字符串操作时,是在堆上创建了一个新的字符串变量,并将新的 ...

  3. 【部分补充】【翻译转载】【官方教程】Asp.Net MVC4入门指南(4):添加一个模型

    4. 添加一个模型 · 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-mo ...

  4. Flask 学习系列(三)---Jinjia2使用过滤器

    再Jinjia2中过滤器是一种转变变量输出内容的技术.··过滤器通过管道符号“|与变量链接,并且可以通过圆括号传递参数” .举例说明: {{my_variable|default('my_variab ...

  5. is 和 == 区别 编码的问题 id()函数

    一丶is 和 == 的区别 == 比较的是值 is 比较的是内存地址 #字符串 a = "abc" b = "abc" print(a == b) print( ...

  6. VC中包含的头文件名不区分大小写

    VC中包含的头文件名,不区分大小写如 #include "my.h" = #include "MY.H".

  7. 【虚拟机-部署】通过 Powershell 来调整 ARM 模式下虚拟机的尺寸

    需求描述 在部署完 ARM 模式的虚拟机以后,可以通过 PowerShell 命令来调整虚拟机的尺寸,以下是通过 PowerShell 命令来调整 ARM 模式的虚拟机尺寸. Note 本文只限于 A ...

  8. userBean-作用范围application

    package com.java1234.model; public class Student { private String name;private int age; public Strin ...

  9. [Git]常用的Git命令行

    Commit的用法 git init [+项目名] git add . (注意这里在add后面的空格和点是不能省略的) git status git commit -m “message”(这里的me ...

  10. python基础教程总结8——特殊方法,属性,迭代器,生成器,八皇后问题

    1. 重写一般方法和特殊的构造方法 1.1 如果一个方法在B类的一个实例中被调用(或一个属性被访问),但在B类中没有找到该方法,那么会去它的超类A里面找. class A: ... def hello ...