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. jquery 事件 多次绑定,多次触发,怎么清除历史绑定事件

    Jquery在处理事件的时候有时候会遇到预想不到的结果 如下 <a id="link_foo">Foo</a> <script type=" ...

  2. http相关概念在iOS中的使用介绍

    http://www.cocoachina.com/ios/20160329/15773.html

  3. ThreadPoolExecutor 分析

    一.从用法入手 Creates a thread pool that creates new threads as needed, but will reuse previously construc ...

  4. 转: svn合并分支到trunk

    http://sepcot.com/blog/2007/04/svn-merge-branch-trunk SVN: Merging a Branch into Trunk   This is mor ...

  5. Javascript实现提示错误的信息直接出现在输入框后

    可以在输入框后加个<span id="error"></span>,当验证错误时这样处理document.getElementById('error').i ...

  6. 如何更改Magento的Base URL

    Magento的Base URL是用于访问商店页面的URL,您也可以为单独一个store view设置一个Base Url.在改这项值之前请确保您的域名已经指向了网站所在服务器的IP,DNS解析完成后 ...

  7. magento多语言中文语言包

    语言包key:http://connect20.magentocommerce.com/community/Mage_Locale_zh_CN

  8. Round and Round We Go

    http://acm.hdu.edu.cn/showproblem.php?pid=1313 考查大整数与小整数相乘 #include<iostream> #include<cstd ...

  9. SQL语句创建表和数据库

      删除数据库,SQL Server将数据库的清单存放在master系统数据库的sysdatabases表中,只需要查看该表是否存在于该数据库中就可以了,语句如下: use master -- 设置当 ...

  10. sell -- 解码16进制unicode

    1. //System.out.println("decodeUnicode:" + decodeUnicode("0049"));//I public sta ...