HDU 1890 Robotic Sort (splay tree)
Robotic Sort
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1640 Accepted Submission(s): 711
In this task, you are to write software for a robot that handles samples in such a laboratory. Imagine there are material samples lined up on a running belt. The samples have different heights, which may cause troubles to the next processing unit. To eliminate such troubles, we need to sort the samples by their height into the ascending order.
Reordering is done by a mechanical robot arm, which is able to pick up any number of consecutive samples and turn them round, such that their mutual order is reversed. In other words, one robot operation can reverse the order of samples on positions between A and B.
A possible way to sort the samples is to find the position of the smallest one (P1) and reverse the order between positions 1 and P1, which causes the smallest sample to become first. Then we find the second one on position P and reverse the order between 2 and P2. Then the third sample is located etc.
The picture shows a simple example of 6 samples. The smallest one is on the 4th position, therefore, the robot arm reverses the first 4 samples. The second smallest sample is the last one, so the next robot operation will reverse the order of five samples on positions 2–6. The third step will be to reverse the samples 3–4, etc.
Your task is to find the correct sequence of reversal operations that will sort the samples using the above algorithm. If there are more samples with the same height, their mutual order must be preserved: the one that was given first in the initial order must be placed before the others in the final order too.
The last scenario is followed by a line containing zero.
Each Pi must be an integer (1 ≤ Pi ≤ N ) giving the position of the i-th sample just before the i-th reversal operation.
Note that if a sample is already on its correct position Pi , you should output the number Pi anyway, indicating that the “interval between Pi and Pi ” (a single sample) should be reversed.
3 4 5 1 6 2
4
3 3 2 1
0
4 2 4 4
splay tree
旋转操作
/* ***********************************************
Author :kuangbin
Created Time :2013/8/24 23:28:43
File Name :F:\2013ACM练习\专题学习\splay_tree_2\HDU1890.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 size[MAXN];//子树规模
int rev[MAXN];//反转标记
int s[MAXN],tot2;//内存池和容量 //debug部分**********************************
void Treavel(int x)
{
if(x)
{
Treavel(ch[x][]);
printf("结点:%2d: 左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d rev = %2d\n",x,ch[x][],ch[x][],pre[x],size[x],rev[x]);
Treavel(ch[x][]);
}
}
void debug()
{
printf("root:%d\n",root);
Treavel(root);
}
//以上是debug部分************************************** void NewNode(int &r,int father,int k)
{
r = k;
pre[r] = father;
ch[r][] = ch[r][] = ;
size[r] = ;
rev[r] = ;
}
//反转的更新
void Update_Rev(int r)
{
if(!r)return;
swap(ch[r][],ch[r][]);
rev[r] ^= ;
}
inline void push_up(int r)
{
size[r] = size[ch[r][]] + size[ch[r][]] + ;
}
inline 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);
}
int n;
void Init()
{
root = tot1 = tot2 = ;
ch[root][] = ch[root][] = pre[root] = size[root] = rev[root] = ;
NewNode(root,,n+);
NewNode(ch[root][],root,n+);
Build(Key_value,,n,ch[root][]);
push_up(ch[root][]);
push_up(root);
}
//旋转,0为左旋,1为右旋
inline void Rotate(int x,int kind)
{
int y = pre[x];
push_down(y);
push_down(x);//先把y的标记下传,在把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);
}
//Splay调整,将r结点调整到goal下面
inline void Splay(int r,int goal)
{
push_down(r);
while(pre[r] != goal)
{
if(pre[pre[r]] == goal)
{
//有反转操作,需要先push_down,再判断左右孩子
push_down(pre[r]);
push_down(r);
Rotate(r,ch[pre[r]][]==r);
}
else
{
//有反转操作,需要先push_down
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;
}
//得到第k个结点(需要push_down)
inline 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);
}
//找前驱(需要push_down)
inline int Get_pre(int r)
{
push_down(r);
if(ch[r][] == )return -;//不存在
r = ch[r][];
while(ch[r][])
{
r = ch[r][];
push_down(r);
}
return r;
}
//找后继(需要push_down)
inline int Get_next(int r)
{
push_down(r);
if(ch[r][] == )return -;
r = ch[r][];
while(ch[r][])
{
r = ch[r][];
push_down(r);
}
return r;
} struct Node
{
int id,val;
}node[MAXN];
bool cmp(Node a,Node b)
{
if(a.val != b.val)return a.val < b.val;
else return a.id < b.id;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d",&n) == && n)
{
for(int i = ;i <= n;i++)
{
scanf("%d",&node[i].val);
node[i].id = i;
}
sort(node+,node+n+,cmp);
Init();
for(int i = ; i <= n;i++)
{
Splay(node[i].id,);
printf("%d",size[ch[root][]]);
if(i < n)printf(" ");
else printf("\n");
Splay(Get_kth(root,i),);
Splay(Get_next(node[i].id),root);
Update_Rev(Key_value);
}
}
return ;
}
HDU 1890 Robotic Sort (splay tree)的更多相关文章
- HDU 1890 Robotic Sort(splay)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1890 [题意] 给定一个序列,每次将i..P[i]反转,然后输出P[i],P[i]定义为当前数字i ...
- hdu 1890 Robotic SortI(splay区间旋转操作)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 题解:splay又一高级的功能,区间旋转这个是用线段树这些实现不了的,这题可以学习splay的旋 ...
- HDU 1890--Robotic Sort(Splay Tree)
题意:每次找出第i大的数的位置p输出,然后将i~p之间的数反转. 题解:每次把要的区间转成一棵子树,然后更新.因为每次将第i小的数转到了了i,所以k次操作后,可知前k个数一定是最小的那k个数,所以以后 ...
- hdu 1890 Robotic Sort(splay 区间反转+删点)
题目链接:hdu 1890 Robotic Sort 题意: 给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次. 题解: 典型的sp ...
- 伸展树(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
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) [Pr ...
- 数据结构(Splay平衡树):HDU 1890 Robotic Sort
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 纸上谈兵:伸展树(splay tree)
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们讨论过,树的搜索效率与树的深度有关.二叉搜索树的深度可能为n,这种情况下,每次 ...
随机推荐
- mvn简单命令
导出maven项目依赖的jar包 mvn dependency:copy-dependencies -DoutputDirectory=lib 编译Java代码 mvn compile eclipse ...
- three.js是什么,能干嘛,和webgl什么关系
如今浏览器的功能越来越强大,而且这些功能可能通过JavaScript直接调用.你可以用HTML5标签轻松地添加音频和视频,而且可以在HTML5画布上创建各种交互组件.现在这个功能集合里又有了一个新成员 ...
- GreenPlum学习笔记:基础知识
一.介绍 GreenPlum分布式数据仓库,大规模并行计算技术. 无共享/MPP核心架构 Greenplum数据库软件将数据平均分布到系统的所有节点服务器上,所以节点存储每张表或表分区的部分行,所有数 ...
- day7回顾
静态方法: 与类无关,不能访问类里的任何属性和方法 类方法: 只能访问类变量 属性@property 把一个方法变成一个静态属性 反射 getattr(obj,str) setattr(obj,str ...
- loadrunner运行时设置中清空缓存方法
用函数web_cache_clearup()或run-time settings---browser emulation 把clear cache on each iteration打勾 W v\] ...
- Kibana部署及配置(四)
一.Kibana安装 Kibana 是为 Elasticsearch 设计的开源分析和可视化平台.你可以使用 Kibana 来搜索,查看存储在 Elasticsearch 索引中的数据并与之交互.你可 ...
- 8-4 Fabled Rooks uva11134
题意:你的任务是在n*n的棋盘上放 n 小于5000 个车 使得任意两个车不互相攻击 且第i个车在一个给定的矩形ri之内 给出该矩形左上角坐标和右下角坐标四个点 必须满足放车的位置在矩形内 边上 ...
- 洛谷P2671 求和 [数论]
题目传送门 求和 格式难调,题面就不放了. 分析: $ZYYS$的一道题. 很显然是大力推公式.我们分析一下题目,实际上限制条件就是:下标同奇偶且颜色相同的数,那么我们先拿这个公式$(x+z)*(nu ...
- Java拾遗补缺
JDK9的lib目录下已经不再包含dt.jar和tool.jar.
- 智能家居实践(番外篇)—— 接入 HomeKit 实现用 Siri 控制家电
转载:智能家居实践(番外篇)—— 接入 HomeKit 实现用 Siri 控制家电 前面我写了一个系列共三篇的智能家居实践,用的是 Amazon Echo 实现语音控制,但是 Amazon Echo ...