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.尤其是我们这里的某人,出模拟试题,居然还出了一道这 ...
随机推荐
- MongoDB的安装与使用
MongoDB是一款NoSql数据库.NoSql数据库叫非关系型数据库,NoSql的全名Not only sql.是为了解决高并发.高可用.高可扩展,以及大数据存储等一系列问题而产生的数据库解决方案. ...
- python基础-类的反射
1)反射是通过字符串方式映射内存中的对象. python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr, 改四个函数分别用于对对象内部执行:检查是 ...
- js写的一些通用方法
Js获取当前浏览器支持的transform兼容写法 // 获取当前浏览器支持的transform兼容写法 function getTransfrom() { var transform = '', / ...
- 深度学习国外课程资料(Deep Learning for Self-Driving Cars)+(Deep Reinforcement Learning and Control )
MIT(Deep Learning for Self-Driving Cars) CMU(Deep Reinforcement Learning and Control ) 参考网址: 1 Deep ...
- 为通过 ATS 检测 Tomcat 完全 TLS v1.2、完全正向加密及其结果检验
2017 年起 app store 要求 app 对接的服务器支持 TLS v1.2,否则 ats 检测不予通过.有点强制推 TLS v1.2 的意味.本文介绍如何使 tomcat 强制执行 TLS ...
- oracle创建job和删除job
https://blog.csdn.net/u010001043/article/details/56479774
- Java学习(Map接口)
一.概述: 我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同,如下图. 1. Collection中的集合,元素是孤立存在的(理解为单身), ...
- day6作业--选课系统
角色:学校.学员.课程.讲师 要求: 1.创建北京.上海2所学校: 2.创建Linux,Python,go 3个课程,Linux\python在北京开,go在上海开: 3.课程包含,周期.价格,通过学 ...
- day6 SYS模块
SYS模块 用于提供对Python解释器相关的操作: (1)sys.argv 命令行参数List,第一个元素是程序本身路径 >>> sys.argv [' ...
- ubuntu12.04上的mongodb卸载
如果您需要卸载 mongodb,然后有几种方法来完成这取决于你想实现. 一.卸载只是 mongodb 这将删除只是 mongodb 包本身. 1 sudo apt-get remove mongodb ...