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. .md文件插图片,不建议使用绝对地址。

    一 主要有两种方法,一种绝对地址,一种相对地址. 而百度的话,全都是说绝对地址的. 但是,有很大的弊端啊 orz 二 先说绝对地址 ![image](https://github.com/AngelS ...

  2. Vue2之页面 、js 、css分离

    在编写vue的时候,页面数据少的时候,可以将所有的js和css都可以直接写在页面上,但是页面数据多,js.css的方法和样式多的时候,都放在一个页面的时候,就显得页面vue十分的臃肿. 所以写项目的时 ...

  3. 部署WebService服务碰到的一个小问题

    在部署WebService服务到IIS上之后,发现一直无法在浏览器访问到编写的asmx文件,一直提示404或403错误.提示当前访问的文件时脚本文件. 1.首先检查了在IIS上部署WebService ...

  4. 基于WebSocket和SpringBoot的群聊天室

    引入 普通请求-响应方式:例如Servlet中HttpServletRequest和HttpServletResponse相互配合先接受请求.解析数据,再发出响应,处理完成后连接便断开了,没有数据的实 ...

  5. R17下maps新增参数的问题

    今天遇到一个奇怪的问题,我之前写的一个函数在我弟弟的机器上编译出错.代码如下: %%将list [k1,v1,k2,v2...]转换成map {k1=>v1,key2=>v2...} -s ...

  6. IDEA创建maven项目的web.xml头

    使用IDEA创建maven项目骨架是webapp时,软件自动创建的web.xml文件是2.3版本的,不能使用el表达式,所以可以手动换成4.0的文件头. <?xml version=" ...

  7. Vuforia切换回识别场景后黑屏解决

    使用Vuforia SDK开发时,如果从其他非识别场景切换回识别场景,可能会出现黑屏问题. 解决方法是在切换到其他场景时,先将当前场景的Tracker信息全部Stop.代码如下: IEnumerato ...

  8. mysql 5.7.20 在线安装与卸载(yum卸载与rpm卸载方式)

    mysql5.7.20和之前的5.7.16版本不同,解压后没有data文件,需要自己建立 1.把下载的mysql5.7.20放到目录:/usr/local/2.卸载cenos上预装的mysql查看已安 ...

  9. Linux安装loadrunner负载机

    1.loadrunner下载地址:http://download.csdn.net/download/intel80586/9542271或者其他资源 2.首先用rpm -qa|grep -i c++ ...

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

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