HDU 3487 Play with Chain (splay tree)
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
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?
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.
CUT 3 5 4
FLIP 2 6
-1 -1
/* ***********************************************
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)的更多相关文章
- HDU 3487 Play with Chain(Splay)
题目大意 给一个数列,初始时为 1, 2, 3, ..., n,现在有两种共 m 个操作 操作1. CUT a b c 表示把数列中第 a 个到第 b 个从原数列中删除得到一个新数列,并将它添加到新数 ...
- HDU 3487 Play with Chain 【Splay】
1-n的序列,有两种操作: 1,将一段区间翻转 2,将一段区间切下来放到剩余序列的第C个数后 采用延迟更新的方法维护区间的翻转,并维护一个size域. 添加一个最大点和一个最小点,防止出界 翻转时,将 ...
- HDU 3478 Play with Chain (Splay树)
这种高级数据结构太难搞了.........现在还是先照着别人的代码敲,做模板..........慢慢花时间来弄懂 #include <iostream> #include <algo ...
- 伸展树(Splay Tree)进阶 - 从原理到实现
目录 1 简介 2 基础操作 2.1 旋转 2.2 伸展操作 3 常规操作 3.1 插入操作 3.2 删除操作 3.3 查找操作 3.4 查找某数的排名.查找某排名的数 3.4.1 查找某数的排名 3 ...
- 数据结构(二) --- 伸展树(Splay Tree)
文章图片和代码来自邓俊辉老师课件 概述 伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由丹尼尔·斯立特Daniel Sleator ...
- HDU 1890 Robotic Sort (splay tree)
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 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 ...
- 纸上谈兵:伸展树(splay tree)
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们讨论过,树的搜索效率与树的深度有关.二叉搜索树的深度可能为n,这种情况下,每次 ...
- bzoj1251 序列终结者(Splay Tree+懒惰标记)
Description 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这 ...
随机推荐
- python网络编程--线程GIL(全局解释器锁)
一:什么是GIL 在CPython,全局解释器锁,或GIL,是一个互斥体防止多个本地线程执行同时修改同一个代码.这把锁是必要的主要是因为当前的内存管理不是线程安全的.(然而,由于GIL存在,其他特性已 ...
- Shell脚本系列教程二: 开始Shell编程
Shell脚本系列教程二: 开始Shell编程 2.1 如何写shell script? (1) 最常用的是使用vi或者mcedit来编写shell脚本, 但是你也可以使用任何你喜欢的编辑器; (2) ...
- TF-图像的深度和通道的概念(转)
图像的深度和通道概念 图像的深度: 图片是由一个个像素点构成的,所有不同颜色的像素点构成了一副完整的图像,计算机存储图片是以二进制来进行的. 1 bit : 用一位来存储,那么这个像素点的取值范围就是 ...
- XP远程连接Win10,提示【远程计算机需要网络级别身份验证,而您的计算机不支持该验证】
最近电脑安装了Win10系统,在办公室可以通过其他电脑远程,但是回去后使用自己的电脑(XP系统)进行远程提示失败, 提示[远程计算机需要网络级别身份验证,而您的计算机不支持该验证],然后上网查找资料, ...
- PHP SPL使用方法 自动加载和迭代器
SPL,PHP 标准库(Standard PHP Library) ,此从 PHP 5.0 起内置的组件和接口,并且从 PHP5.3 已逐渐的成熟.SPL 其实在所有的 PHP5 开发环境中被内置,同 ...
- Service(一):认识service、绑定Service
Activity是与用户打交道的,而Service是在后台运行的. 这个程序介绍了下如何启动和停止一个Service,以及在后台打印消息,我添加了一些注释. 在activity_main中将布局改为线 ...
- virtualenv,virtualenvwrapper安装及使用
1.安装 # 安装: (sudo) pip install virtualenv virtualenvwrapper # centos7下 pip install virtualenv virtual ...
- 【[国家集训队]小Z的袜子】
对于L,R的询问.设其中颜色为x,y,z的袜子的个数为a,b,c...那么答案即为(a*(a-1)/2+b*(b-1)/2+c*(c-1)/2....)/((R-L+1)*(R-L)/2)化简得:(a ...
- 使用T-SQL导入多个文件数据到SQL Server中
在我们的工作中,经常需要连续输入多个文件的数据到SQL Server的表中,有时需要从相同或者不同的目录中,同时将文件中的数据倒入.在这篇文章中,我们将讨论如何同时把一个目录中的文件的数据倒入到SQL ...
- return to dl_resolve无需leak内存实现利用
之前在drop看过一篇文章,是西电的Bigtang师傅写的,这里来学习一下姿势做一些笔记. 0x01 基础知识 Linux ELF文件存在两个很重要的表,一个是got表(.got.plt)一个是plt ...