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. Java 多线程概念

    1.为什么要使用多线程: 更多的处理器核心. 更快的响应时间. 更好的变成模型. 2.线程的优先级: 现代操作系统基本采用时分的形式调度运行的线程,操作系统会分出一个个的时间片,线程会分配到若干时间片 ...

  2. Rest_framework之版本控制、响应器和分页器

    一.访问频率补充 频率: 自定义: 1 定义一个类MyThrottles allow_request(频率限制的逻辑) ==>这两个函数都是派生出来的,继承的类里面封装的. wait(返回一个数 ...

  3. 从0到1分步实现一个出生日期的正则表达式(JavaScript)

    简言 在表单验证中,经常会用正则表达式做出生日期校验.本文把出生日期分割成几个部分,分步地介绍了实现一个出生日期校验的完整过程.相信您在理解了本篇的内容后,对如何编写和如何应用正则表达式会有进一步的理 ...

  4. hive中select中DISTINCT的技巧和使用

    hive中select中DISTINCT的技巧和使用 单表的唯一查询用:distinct 多表的唯一查询用:group by 在使用MySQL时,有时需要查询出某个字段不重复的记录,虽然mysql提供 ...

  5. Golang的开发环境配置之SlickEdit篇

    Golang的开发环境通常有如下三种: 1. vi, emacs, notepad++ 2. Sublime Text 2/3 3. LiteIDE 不过,今天我想体验一下在slickedit当中使用 ...

  6. Android商城开发系列(六)——使用 OkHttpUtils 请求网络 + 使用 fastjson解析数据

    OkHttp是Google推荐使用的一个开源的网络请求框架,Android开发中涉及到网络请求和接口调用现在大部分都是使用OkHttp,网上已经有不少人针对OkHttp进行了封装,这里推荐一下鸿洋大神 ...

  7. 机器学习经典算法之SVM

    SVM 的英文叫 Support Vector Machine,中文名为支持向量机.它是常见的一种分类方法,在机器学习中,SVM 是有监督的学习模型. 什么是有监督的学习模型呢?它指的是我们需要事先对 ...

  8. 日常-acm-韩信点兵

    相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排,五人一排,七人一排地变换队形,而他每次只看一眼队伍的排尾就知道人数了.输入包含多组数据,每组数据包含三个非负整数a,b,c,表示 ...

  9. 剑指offer38 数字在排序数组中出现的次数

    这种方法没用迭代,而是使用了循环的方式 class Solution { public: int GetNumberOfK(vector<int> data ,int k) { if(da ...

  10. javaweb基础(21)_两种开发模式

    SUN公司推出JSP技术后,同时也推荐了两种web应用程序的开发模式,一种是JSP+JavaBean模式,一种是Servlet+JSP+JavaBean模式. 一.JSP+JavaBean开发模式 1 ...