http://acm.hdu.edu.cn/showproblem.php?pid=1890

Robotic Sort


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的无序数列a,然后按照一定规则进行反转,到第i个点时,找一个区间[a,b],a=i,b是第i大元素所在的下标,然后把区间进行反转,如果存在多个相同大小的元素,则要保证他们在原始数列的相对顺序不变
分析:对于原始数列,把他们每个数对应的key值依次初始化为1-n,然后用p[i].val记录第i个点值,p[i].pri记录第i个值是第几次出现,主要解决相对位置问题,p[i].key记录第i个元素对应的key值,然后把p从小到大排序,当搜索到第i个元素的时候,则p[i].val就是第i大元素,根据p[i].key在splsy树中找出该键值在序列中的实际顺序下标b,然后把第a-1个元素反转到树根,把第b+1个旋转到树根的右儿子出,然后对树根的右儿子的左儿子进行标记
code:
#include"stdio.h"
#include"iostream"
#include"queue"
#include"string.h"
#include"map"
#include"stdlib.h"
#include"algorithm"
#include"string"
#define M 1000005
#define inf 0x3f3f3f3f
using namespace std;
int a[M];
struct P
{
int val,pri,key;
}p[M];
int top,root;
int cmp(P a,P b)
{
if(a.val==b.val)
return a.pri<b.pri;
return a.val<b.val;
}
int son[M][],fa[M],num[M],flip[M],child[M];
struct Text
{
queue<int>q;
void init(int n)
{
top=n+;
for(int i=;i<=n+;i++)
{
num[i]=;
son[i][]=son[i][]=-;
fa[i]=-;
flip[i]=;
}
}
void Rotate(int x,int k)
{
int y=fa[x]; son[y][^k]=son[x][k];
if(son[y][^k]!=-)
fa[son[y][^k]]=y;
push_up(y);
if(son[fa[y]][]==y)
son[fa[y]][]=x;
else
son[fa[y]][]=x;
fa[x]=fa[y]; son[x][k]=y;
fa[y]=x;
}
void splay(int x,int f)
{
if(x==-)return;
while(fa[x]!=f)
{
int y=fa[x];
int z=fa[y];
if(z==f)
{
if(son[y][]==x)
Rotate(x,);
else
Rotate(x,);
}
else
{
if(son[z][]==y)
{
if(son[y][]==x)
{
Rotate(y,);
Rotate(x,);
}
else
{
Rotate(x,);
Rotate(x,);
}
}
else
{
if(son[y][]==x)
{
Rotate(y,);
Rotate(x,);
}
else
{
Rotate(x,);
Rotate(x,);
}
}
}
}
if(f==top)
root=x;
}
void RotateTo(int k,int f)
{
k++;
int x=root;
while()
{
push_down(x);
int temp=getNum(son[x][])+;
if(k==temp)break;
else if(k<temp)
x=son[x][];
else
{
k-=temp;
x=son[x][];
}
}
splay(x,f);
push_up(x);
}
int getOrder(int x)
{
int y=x;
while(fa[y]!=top)
{
int f=fa[y];
child[f]=y;
y=fa[y];
}
y=root;
while(y!=x)
{
int z=child[y];
push_down(z);
y=child[y];
}
int k=getNum(son[x][])+;
while(fa[x]!=top)
{
int y=fa[x];
int temp=getNum(son[y][])+;
if(son[y][]==x)
x=fa[x];
else
{
k+=temp;
x=fa[x];
}
}
return k-;
}
void Reversal(int x)
{
if(x==-)return;
int y=son[x][];
son[x][]=son[x][];
son[x][]=y;
}
int getNum(int x)
{
if(x==-)return ;
return num[x];
}
void push_up(int x)
{
num[x]=getNum(son[x][])+getNum(son[x][])+;
}
void push_down(int x)
{
if(x==-)return;
if(flip[x])
{
flip[x]^=;
Reversal(x);
if(son[x][]!=-)
flip[son[x][]]^=;
if(son[x][]!=-)
flip[son[x][]]^=;
}
}
void creat(int l,int r,int k,int f)
{
if(l>r)return;
int mid=(l+r)/;
if(f==top)
root=mid;
son[f][k]=mid;
fa[mid]=f;
creat(l,mid-,,mid);
creat(mid+,r,,mid);
push_up(mid);
}
void dfs(int x,int n)
{
if(x==-)return;
push_down(x);
dfs(son[x][],n);
if(x>=&&x<=n)
q.push(a[x]);
dfs(son[x][],n);
}
void output(int n)
{
dfs(root,n);
printf("%d",q.front());
q.pop();
while(!q.empty())
{
printf(" %d",q.front());
q.pop();
}
puts("");
}
}; int main()
{
int n;
while(scanf("%d",&n),n)
{
Text text;
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
map<int,int>mp;
p[].val=-inf;
p[].pri=;
p[].key=;
for(int i=;i<=n;i++)
{
p[i].val=a[i];
p[i].pri=mp[a[i]];
p[i].key=i;
mp[a[i]]++;
}
p[n+].val=inf;
p[n+].pri=;
p[n+].key=n+;
sort(p,p+n+,cmp);
text.init(n);
text.creat(,n+,,top);
for(int i=;i<=n;i++)
{
int l=i-;
int key=p[i].key;
int r=text.getOrder(key)+;
text.RotateTo(l,top);
text.RotateTo(r,root);
flip[son[son[root][]][]]^=;
//text.output(n);
if(i==)
printf("%d",r-);
else
printf(" %d",r-);
}
puts("");
}
return ;
}

HDU 1890 区间反转的更多相关文章

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

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

  2. hdu1890 伸展树(区间反转)

    对于大神来说这题是水题.我搞这题花了快2天. 伸展树的优点有什么,就是树不管你怎么旋转序列是不会改变得,并且你要使区间反转,只要把第k大的点转到根结点,那么它的左子树就是要交换的区间[l,r),然后交 ...

  3. 算法模板——splay区间反转 2

    实现功能:同splay区间反转 1(基于BZOJ3223 文艺平衡树) 这次改用了一个全新的模板(HansBug:琢磨了我大半天啊有木有),大大简化了程序,同时对于splay的功能也有所完善 这里面没 ...

  4. 算法模板——splay区间反转 1

    实现的功能:将序列区间反转,并维护 详见BZOJ3223 var i,j,k,l,m,n,head,a1,a2:longint; s1:ansistring; a,b,c,d,fat,lef,rig: ...

  5. hdu 5869 区间不同GCD个数(树状数组)

    Different GCD Subarray Query Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K ( ...

  6. hdu 4283 区间dp

    You Are the One Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  7. hdu 5700区间交(线段树)

    区间交 Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...

  8. HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化

    HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化 n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的 ...

  9. 2018牛客网暑期ACM多校训练营(第三场) H - Shuffle Cards - [splay伸展树][区间移动][区间反转]

    题目链接:https://www.nowcoder.com/acm/contest/141/C 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K ...

随机推荐

  1. he time that it takes to bring a block from disk into main memory

    DATABASE SYSTEM CONCEPTS, SIXTH EDITION There is a trade-off that the system designer must make betw ...

  2. Lazarus解决无法识别中文路径的方法

    procedure TForm1.Button1Click(Sender: TObject); var FileN:string; begin if self.OpenDialog1.Execute ...

  3. Android Studio 快捷键使用

    最近开始全面转向Android Studio开发了,经常要去查快捷键,索性汇总下,自己方便查找 IDE 按键    说明 F1 帮助 Alt(Option)+F1 查找文件所在目录位置 Alt(Opt ...

  4. Myeclipse配置 项目编码格式

    修改MyEclipse 工作空间的编码 修改之后,在该工作空间下创建的任何项目,编码都是UTF-8,既,该项目下所有文件都是utf-8 格式,工作空间影响项目,项目影响文件 General --> ...

  5. IOS常见的三种回调方法介绍

    认识下三种IOS常见的回调模式. 代理模式作为IOS中最常见的通讯模式,代理几乎无处不在. 这里有一个数组,我们首先通过代理的方式将数组传递到其他方法中去. 设置协议及方法 @protocol Cal ...

  6. 在脚本中操作plist文件

    终端输入: /usr/libexec/PlistBuddy -c "Print CFBundleIdentifier" /Users/achen/Desktop/testBundl ...

  7. mysql基本sql语句大全(提升用语篇)

    1.说明:复制表(只复制结构,源表名:a 新表名:b) (Access可用) 法一:select * into b from a where 1<>1(仅用于SQlServer) 法二:s ...

  8. r.js 前端项目打包

    目录结构

  9. TermServDevices报错导致服务器死机(远程服务使用者必读)

    事件类型: 错误 事件来源: TermServDevices 事件 ID: 1111 描述:打印机 !!192.168.99.6!HP LaserJet 3050 Series PCL 5e 所需的驱 ...

  10. getconf 命令

    getconf 命令 用途 将系统配置变量值写入标准输出. 系统的默认参数,比如mkfs读取默认参数,并格式化,默认PAGESIZE是4096 语法 getconf [ -v specificatio ...