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. jQuery:如何给动态生成的元素绑定事件?

    jQuery的html()可以给现在元素附加新的元素,innerHTML也可以,那么,如何给这些新生成的元素绑定事件呢?直接在元素还未生成前就绑定肯定是无效的,因为所绑定的元素目前根本不存在. 然而, ...

  2. Ionic开发-搭建开发环境

    1安装node.js 2安装ionic & cordova: 命令行输入:npm install –g cordova ionic 注:-g表示全局安装,也可以进入指定的目录安装,但这里推荐全 ...

  3. centOS 下开启端口号

    firewall-cmd --zone=public --add-port=80/tcp --permanent permanent参数表示永久生效 更新防火墙规则  firewall-cmd --r ...

  4. MySQL连表Update修改数据

    设想两张表,如下 table A field id field name table B field id filed my_name 现在希望将表B中的my_name中的内容“拷贝”到表A中对应的n ...

  5. shareTo 网页版分享

    // share -------- var shareTo = function (dest, shareCode) { var appKey = "1667889534"; // ...

  6. [SecureCRT]通过SFTP方式上传本地文件到服务器

    1.在本地建一个文件夹,如:d:\My Documents,在此目录下,放入我们需要上传的文件,如:nmon_linux_x86_64 2.然后打开我们的SecureCRT工具,一次选择Options ...

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

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

  8. python中os.listdir( )函数读取文件夹

    编写pytohn脚本时通常需要批处理. 列出指定目录下的所有文件/文件夹 os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表,但有个很明显的缺点,它的默认顺序不是有序的或 ...

  9. 课外作业1:将一个double类型的小数,按照四舍五入保留两位小数

    package come.one01; public class One02 { public static void main(String[] args) { double numa = 3.14 ...

  10. IDEA安装及破解

    一.下载(IDEA 2019.1.2) 1.下载地址:https://www.jetbrains.com/idea/download/#section=windows 2.选择版本,并选择最终版(.e ...