Robotic Sort

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3913    Accepted Submission(s): 1717

Problem Description
Somewhere deep in the Czech Technical University buildings, there are laboratories for examining mechanical and electrical properties of various materials. In one of yesterday’s presentations, you have seen how was one of the laboratories changed into a new multimedia lab. But there are still others, serving to their original purposes.

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.

 
Input
The input consists of several scenarios. Each scenario is described by two lines. The first line contains one integer number N , the number of samples, 1 ≤ N ≤ 100 000. The second line lists exactly N space-separated positive integers, they specify the heights of individual samples and their initial order.

The last scenario is followed by a line containing zero.

 
Output
For each scenario, output one line with exactly N integers P1 , P1 , . . . PN ,separated by a space.
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.

 
Sample Input
6
3 4 5 1 6 2
4
3 3 2 1
0
 
Sample Output
4 6 4 5 6 6
4 2 4 4

题意:n个试管,每次找最短的位置p[i]输出,翻转i~p[i]

没想到写了好长时间
对序列的理解:
1.build之后数组下标就是序列编号,中序遍历就是序列
2.这样的splay并没有左小右大的关系,因为有反转操作
3.加哨兵之后,翻转序列[l,r],就是处理kth(l)和kth(r+2)
 
一开始想了很多应该处理哪个序列,都错了
其实题目已经很清楚了,就是翻转i~p[i]
处理第i短的编号为x,x就是序列编号就是数组下标,把x splay到根然后p[i]=左子树大小+1(就是t[lc].size 因为1是哨兵)
翻转操作就是rever(i,t[lc].size);
 
关于标记下传:
1.翻转操作先要kth,在kth中下传了就没必要在splay中下传了
2.否则的话先从x找到tar,然后从tar往x下传标记,最后splay(x,tar)
 
//
// main.cpp
// hdu1890
//
// Created by Candy on 30/11/2016.
// Copyright © 2016 Candy. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define pa t[x].fa
#define lc t[x].ch[0]
#define rc t[x].ch[1]
const int N=1e5+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
struct node{
int fa,ch[],w,size,flp;
}t[N];
int root;
inline void update(int x){t[x].size=t[lc].size+t[rc].size+t[x].w;}
inline int wh(int x){return t[pa].ch[]==x;}
inline void pushDown(int x){
if(t[x].flp){
swap(lc,rc);
t[lc].flp^=;t[rc].flp^=;
t[x].flp=;
}
}
inline void rotate(int x){
int f=t[x].fa,g=t[f].fa,c=wh(x);
if(g) t[g].ch[wh(f)]=x;t[x].fa=g;
t[f].ch[c]=t[x].ch[c^];t[t[f].ch[c]].fa=f;
t[x].ch[c^]=f;t[f].fa=x;
update(f);update(x);
}
inline void splay(int x,int tar){
for(;t[x].fa!=tar;rotate(x))
if(t[pa].fa!=tar) rotate(wh(pa)==wh(x)?pa:x);
if(tar==) root=x;
}
int ne[N];
void spl(int x,int tar){
int _=x;
while(x!=tar) ne[pa]=x,x=pa;
x=_;
for(int i=tar;i!=x;i=ne[i]) pushDown(i);
pushDown(x);
splay(x,tar);
}
int build(int l,int r){
if(l>r) return ;
int x=(l+r)>>;
lc=build(l,x-);rc=build(x+,r);
t[lc].fa=t[rc].fa=x;
t[x].w=;t[x].flp=;
update(x);
//printf("build %d %d %d\n",x,lc,rc);
return x;
}
int kth(int k){
int x=root,ls=;
while(x!=){
pushDown(x);
int _=ls+t[lc].size;
if(_<k&&k<=_+t[x].w) return x;
if(k<=_) x=lc;
else ls=_+t[x].w,x=rc;
}
return -;
}
void rever(int l,int r){//printf("rev %d %d ",l,r);
splay(kth(l),);
int x=kth(r+);//printf("x %d\n",x);
splay(x,root);
t[lc].flp^=;
}
int n;
struct data{
int id,v;
bool operator <(const data &a)const{
if(v==a.v) return id<a.id;
return v<a.v;
}
}a[N];
int main(int argc, const char * argv[]){
while(scanf("%d",&n)!=EOF&&n){
memset(t,,sizeof(t));
for(int i=;i<=n;i++) a[i].v=read(),a[i].id=i+;
sort(a+,a++n);
root=build(,n+);
for(int i=;i<=n;i++){
int x=a[i].id;//printf("hi %d %d\n",i,x);
spl(x,);
printf("%d%c",t[lc].size,i<n?' ':'\n');
rever(i,t[lc].size);
}
}
return ;
}
 
 
 

HDU1890 Robotic Sort[splay 序列]的更多相关文章

  1. hdu1890 Robotic Sort (splay+区间翻转单点更新)

    Problem Description Somewhere deep in the Czech Technical University buildings, there are laboratori ...

  2. HDU1890 Robotic Sort Splay tree反转,删除

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 题目中涉及数的反转和删除操作,需要用Splay tree来实现.首先对数列排序,得到每个数在数列 ...

  3. HDU 1890 Robotic Sort | Splay

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) [Pr ...

  4. BZOJ 1552: [Cerc2007]robotic sort( splay )

    kpm大神说可以用块状链表写...但是我不会...写了个splay.... 先离散化 , 然后splay结点加个min维护最小值 , 就可以了... ( ps BZOJ 3506 题意一样 , 双倍经 ...

  5. hdu 1890 Robotic Sort(splay 区间反转+删点)

    题目链接:hdu 1890 Robotic Sort 题意: 给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次. 题解: 典型的sp ...

  6. 【BZOJ1552】[Cerc2007]robotic sort Splay

    [BZOJ1552][Cerc2007]robotic sort Description Input 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N ...

  7. 【bzoj1552/3506】[Cerc2007]robotic sort splay翻转,区间最值

    [bzoj1552/3506][Cerc2007]robotic sort Description Input 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000. ...

  8. [BZOJ1552] [Cerc2007] robotic sort (splay)

    Description Input 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号. Output ...

  9. HDU 1890 - Robotic Sort - [splay][区间反转+删除根节点]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 Time Limit: 6000/2000 MS (Java/Others) Memory Li ...

随机推荐

  1. [C#] .NET4.0中使用4.5中的 async/await 功能实现异

    好东西需要分享 原文出自:http://www.itnose.net/detail/6091186.html 在.NET Framework 4.5中添加了新的异步操作库,但是在.NET Framew ...

  2. discuz X3.1 关于分表 和 分表数据迁移

    // *********** 关于读取分表的数据*********** { // forum_thread 分表代码片段 -- 帖子列表 { // 定位某个板块的帖子落在哪个表(forum_threa ...

  3. springmvc添加mock json的支持

    在springmvc中 添加对服务器classPath下的json文件解析之后返回的mock功能: import java.io.FileNotFoundException; import java. ...

  4. python之redis和memcache操作

    Redis 教程 Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理.Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据 ...

  5. [Cordova] Plugin开发架构

    [Cordova] Plugin开发架构 问题情景 开发Cordova Plugin的时候,侦错Native Code是一件让人困扰的事情,因为Cordova所提供的错误讯息并没有那么的完整.常常需要 ...

  6. jQuery实现页面内锚点平滑跳转

    平时我们做导航滚动到内容都是通过锚点来做,刷的一下就直接跳到内容了,没有一丝的滚动效果,而且 url 链接最后会有“小尾巴”,就像#keleyi,今天我就介绍一款 jquery 做的滚动的特效,既可以 ...

  7. vs2012使用64位IIS EXPRESS调试

    使用Visual Studio 2012开发网站或web应用程序时,可以使用两种web server.自带的development server和IIS EXPRESS.development ser ...

  8. 完美 全兼容 解决 文字两端对齐 justify 中文姓名对齐

    text-align:justify; 所有浏览器都支持,text-justify之类的却只有IE支持,就不要考虑了. justify我的理解,使元素内部的子元素两端对齐,子元素当然只能是inline ...

  9. DOM事件揭秘-事件流

    事件:文档/窗口中发生的特定的交互瞬间 瀑布流,图片轮播 动作都是通过事件触发的 课程内容: 1,理解事件流 2,使用时间处理程序 3,不同的事件类型 ie4.0以后, 事件流:描述的是从页面中接收事 ...

  10. iOS Swift-注释与分号

    iOS Swift-注释与分号 注释 注释是每门语言都存在的一种解释方式,Swift的注释与C语言的注释非常相似,单行注释采用//. //这是一个注释 在Swift中也可以使用多行注释,起始标记使用( ...