HDU 1890 Robotie 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。要将这段序列进行排序。排序的方式是通过每次找出第i大数与它本来的位置一段序列进行反转,相当于一次排序、也就相当于反转N次,要求每次输出反转前第i大位置的数的位置。

  每组输入数据包括两行,第一行输入序列长度N,第二行输入该序列。

  输出数据包括N个数字,Pi~PN。Pi表示第i次反转前第i大的位置。

AC代码如下:

  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<string.h>
  4 using namespace std;
  5 #define N 500006
  6 #define lc (tr[id].c[0])
  7 #define rc (tr[id].c[1])
  8 #define key (tr[tr[root].c[1]].c[0])
  9 struct tree
 10 {
 11     int fa,sum,c[2],lz,v;
 12 }tr[N];
 13 struct point
 14 {
 15     int v,id;
 16     bool operator<(const point a)const
 17     {
 18         if(a.v==v)return id<a.id;
 19         else return v<a.v;
 20     }
 21 }so[N/5];
 22 int tot,root,n;
 23 int xia[N];
 24 int newpoint(int d,int f)
 25 {
 26     tr[tot].sum=1;
 27     tr[tot].v=d;
 28     tr[tot].c[0]=tr[tot].c[1]=-1;
 29     tr[tot].lz=0;
 30     tr[tot].fa=f;
 31     return tot++;
 32 }
 33 void push(int id)
 34 {
 35     int lsum,rsum;
 36     if(lc==-1)lsum=0;
 37     else lsum=tr[lc].sum;
 38     if(rc==-1)rsum=0;
 39     else rsum=tr[rc].sum;
 40     tr[id].sum=lsum+rsum+1;
 41 }
 42 int build(int l,int r,int v)
 43 {
 44     if(r<l)return -1;
 45     int mid=(r+l)>>1;
 46     int ro=newpoint(mid,v);
 47     xia[mid]=ro;
 48     tr[ro].c[0]=build(l,mid-1,ro);
 49     tr[ro].c[1]=build(mid+1,r,ro);
 50     push(ro);
 51     return ro;
 52 }
 53 void lazy(int id)
 54 {
 55     if(tr[id].lz)
 56     {
 57         swap(lc,rc);
 58         tr[lc].lz^=1;
 59         tr[rc].lz^=1;
 60         tr[id].lz=0;
 61     }
 62 }
 63
 64 void xuanzhuan(int x,int k)
 65 {
 66     if(tr[x].fa==-1)return ;
 67     int fa=tr[x].fa;
 68     int w;
 69     lazy(fa);
 70     lazy(x);
 71     tr[fa].c[!k]=tr[x].c[k];
 72     if(tr[x].c[k]!=-1)tr[tr[x].c[k]].fa=fa;
 73     tr[x].fa=tr[fa].fa;
 74     tr[x].c[k]=fa;
 75     if(tr[fa].fa!=-1)
 76     {
 77         w=tr[tr[fa].fa].c[1]==fa;
 78         tr[tr[fa].fa].c[w]=x;
 79     }
 80     tr[fa].fa=x;
 81     push(fa);
 82     push(x);
 83 }
 84
 85 void splay(int x,int goal)
 86 {
 87     if(x==-1)return ;
 88     lazy(x);
 89     while(tr[x].fa!=goal)
 90     {
 91         int y=tr[x].fa;
 92         lazy(tr[y].fa);
 93         lazy(y);
 94         lazy(x);
 95         bool w=(x==tr[y].c[1]);
 96         if(tr[y].fa!=goal&&w==(y==tr[tr[y].fa].c[1]))xuanzhuan(y,!w);
 97         xuanzhuan(x,!w);
 98     }
 99     if(goal==-1)root=x;
100     push(x);
101 }
102 int next(int id)
103 {
104     lazy(id);
105     int p=tr[id].c[1];
106     if(p==-1)return id;
107     lazy(p);
108     while(tr[p].c[0]!=-1)
109     {
110         p=tr[p].c[0];
111         lazy(p);
112     }
113     return p;
114 }
115 int main()
116 {
117     while(scanf("%d",&n),n)
118     {
119         for(int i=1;i<=n;i++)
120         {
121             scanf("%d",&so[i].v);
122             so[i].id=i;
123         }
124         sort(so+1,so+n+1);
125         so[0].id=0;
126         tot=0;
127         int d,l;
128         root=build(0,n+1,-1);
129         for(int i=1;i<=n;i++)
130         {
131             int ro=xia[so[i].id];
132             int ne;
133             splay(ro,-1);
134             d=tr[tr[root].c[0]].sum;
135             l=xia[so[i-1].id];
136             ne=next(ro);
137             splay(l,-1);
138             splay(ne,root);
139             lazy(root);
140             lazy(tr[root].c[1]);
141             tr[key].lz^=1;
142             if(i!=1)printf(" ");
143             printf("%d",d);
144         }
145         printf("\n");
146     }
147     return 0;
148 }

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1890

(本人蒟蒻,代码也是看书上敲的,以后应该会慢慢成长吧)

时间: 2024-08-27 07:59:18

HDU 1890 Robotie Sort的相关文章

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

题目链接:hdu 1890 Robotic Sort 题意: 给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次. 题解: 典型的splay区间翻转+删点. 我们把数据排序,然后记录一下每个数原来的位置,然后splay建树的时候用原来的位置来对应,这样val[i].second就直接是这个数在splay中的那个节点. (当然你也可以普通建树,然后手动记录位置). 然后我们把要找的那个数对应的节点旋转到根,然后根左边的size+i就

HDU 1890 Robotic Sort

题意: 将一列数字排序  排序规则是  每次找到最小值的位置loc  将1~loc所有数字颠倒  然后删掉第一位  直到排好序  排序要求是稳定的 思路: 这题要做的是  寻找区间最小值位置  翻转区间  的操作  因此可以想到用splay 只需要每个节点记录一个small  就可以实现找到最小值位置 翻转区间操作就是将splay的超级头转到最上面使之成为根  再把loc转到根下面  这时根的右儿子的左儿子就是需要翻转的区间  用一个rev延迟更新  然后将loc转到最上面是指成为根  删掉根

HDU 1890 Robotic Sort 伸展树的区间反转与延迟标记

延迟标记像极了线段树,不再多说. 区间反转在树伸展到位之后,也变成了简单的递归交换左右儿子. 愈发感觉到伸展树简直太漂亮了,伸展操作更是诱惑到不行 ,总之数据结构太有魅力了. 比较简单,就直接上模板了. #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #in

HDU 1890 Robotic Sort(splay)

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1890 [题意] 给定一个序列,每次将i..P[i]反转,然后输出P[i],P[i]定义为当前数字i的所在位置.相等的两个数排序后相对位置不变. [思路] 由于相对位置不变,所以可以根据数值与位置重编号. 依旧使用直接定位从上到下旋转至根的splay写法.每次将i结点旋转至根,则答案为左儿子大小+i,然后将i删掉合并左右儿子. 需要注意合并时判断左右儿子是否为空,以及各种pushdown下传标记.

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description Somewhere deep in the Czech Technical University buildings, there are laboratories for examining

HDU 1890 Robotic Sort (Splay)

题意:将一列数字排序  排序规则是  每次找到最小值的位置loc  将1~loc所有数字颠倒  然后删掉第一位  直到排好序  排序要求是稳定的. 析:直接用splay来维护最小值,然后插入删除即可. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include

数据结构(Splay平衡树):HDU 1890 Robotic Sort

Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3456    Accepted Submission(s): 1493 Problem Description Somewhere deep in the Czech Technical University buildings, there are labora

Splay练习题 [HDU 1890] Robotic Sort

Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2495    Accepted Submission(s): 1107 Problem Description Somewhere deep in the Czech Technical University buildings, there are labor

HDU 1890 Splay区间翻转

D - Robotic Sort Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1890 Appoint description:  System Crawler  (2014-11-27) Description Somewhere deep in the Czech Technical University buildings, t