Description

一个实验室里有n个长短不一的试管。你的任务是编写一段程序,用机器臂把它们按照高度从小到大的顺序排列。

对于高度相同的试管,排序前后的相对位置应保持不变。排序方法如图所示。



排序需要n次操作,其中第i次操作是反转序列i ~ Pi,其中Pi是目标状态中第i个试管当前所在的位置。比如,在上图中,初始时P1=4,因此反转试管1 ~ 4就能把最左边的试管归位。类似地,第2次操作前P2=6,因此反转2 ~ 6就能把左数第2个试管归位。你的任务是输出P1,P2,…,Pn的值,以便控制机器臂移动。注意i=Pi时实际上不需要反转,但仍然需要输出Pi。

Input

输入包含多组测试数据。每组数据第一行为试管个数n(1≤n≤100000),第二行从左到右依次为每个试管的高度。输入以0结束。

Output

对于每组数据输出一行,依次为P1,P2,…,Pn。

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


记录一个pos[x],代表以x为根的子树内的最小编号,那么每次查询[i,n]中的最小值,然后把该点splay到根后,左子树的大小就是答案,然后维护一个翻转标记即可。建树的时候不能建成一条链,要递归建成一棵树

/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
inline void print(int x){
if (x>=10) print(x/10);
putchar(x%10+'0');
}
const int N=1e5;
struct AC{
int val,pos;
void join(int i){val=read(),pos=i;}
}A[N+10];
bool cmp(AC x,AC y){return x.val!=y.val?x.val<y.val:x.pos<y.pos;}
bool cmp1(AC x,AC y){return x.pos<y.pos;}
struct Splay{
#define T(x) (tree[f[x]][1]==x)
#define ls (tree[x][0])
#define rs (tree[x][1])
int tree[N+10][2],f[N+10],size[N+10],Min[N+10],v[N+10],pos[N+10],ans[N+10];
bool flag[N+10];
int root,n;
void updata(int x){
size[x]=size[ls]+size[rs]+1;
Min[x]=v[x],pos[x]=x;
if (Min[x]>Min[ls]){Min[x]=Min[ls];pos[x]=pos[ls];}
if (Min[x]>Min[rs]){Min[x]=Min[rs];pos[x]=pos[rs];}
}
void pushdown(int x){
if (!flag[x]) return;
flag[ls]^=1;
flag[rs]^=1;
swap(ls,rs);
flag[x]=0;
}
void build(int fa,int l,int r){
if (l>r) return;
if (l==r){
f[l]=fa,size[l]=1;
l<fa?tree[fa][0]=l:tree[fa][1]=l;
v[l]=Min[l]=A[l].val,pos[l]=l;
return;
}
int mid=(l+r)>>1;
build(mid,l,mid-1),build(mid,mid+1,r);
f[mid]=fa,v[mid]=A[mid].val;
mid<fa?tree[fa][0]=mid:tree[fa][1]=mid;
updata(mid);
}
void move(int x){
int fa=f[x],son=tree[x][T(x)^1];
tree[x][T(x)^1]=fa;
tree[fa][T(x)]=son;
if (son) f[son]=fa;
f[x]=f[fa];
if (f[x]) tree[f[x]][T(fa)]=x;
f[fa]=x;
updata(fa),updata(x);
}
void up(int x){
if (!x) return;
up(f[x]);
pushdown(x);
}
void splay(int x){
up(x);
while (f[x]){
if (f[f[x]]) T(x)==T(f[x])?move(f[x]):move(x);
move(x);
}
root=x;
}
int find(int x,int i){
if (!i) return 0;
pushdown(i);
if (size[tree[i][0]]+1==x) return i;
if (x<=size[tree[i][0]]) return find(x,tree[i][0]);
return find(x-size[tree[i][0]]-1,tree[i][1]);
}
void filp(int x,int y){
x=find(x,root),splay(x);
y=find(y+2,root),splay(y);
if (f[x]!=root) move(x);
flag[tree[x][1]]^=1;
}
int query(int x,int y){
x=find(x,root),splay(x);
y=find(y+2,root),splay(y);
if (f[x]!=root) move(x);
return pos[tree[x][1]];
}
void init(){
n=read(),root=(n+3)>>1;
if (!n) exit(0);
A[1].val=A[n+2].val=Min[0]=inf;
for (int i=2;i<=n+1;i++) A[i].join(i);
sort(A+2,A+2+n,cmp);
for (int i=2;i<=n+1;i++) A[i].val=i;
sort(A+2,A+2+n,cmp1);
build(0,1,n+2);
}
void work(){
init();
for (int i=1;i<=n;i++){
int x=query(i,n);
splay(x);
ans[i]=size[tree[x][0]];
filp(i,ans[i]);
}
for (int i=1;i<=n;i++) i!=n?printf("%d ",ans[i]):printf("%d\n",ans[i]);
}
}T;
int main(){
T.work();
return 0;
}

[CREC2007/CQOI2014]robotic sort的更多相关文章

  1. [bzoj1552\bzoj2506][Cqoi2014]robotic sort 排序机械臂_非旋转Treap

    robotic sort 排序机械臂 bzoj-1552 bzoj-2506 Cqoi-2014 题目大意:给定一个序列,让你从1到n,每次将[1,p[i]]这段区间反转,p[i]表示整个物品权值第i ...

  2. 【BZOJ】【1552】【Cerc2007】robotic sort / 【3506】【CQOI2014】排序机械臂

    Splay 离散化+Splay维护序列…… 好吧主要说一下我做这道题遇到的几个错误点: 1.离散化 2.由于找到的这个数的位置一定是大于等于 i 的,所以其实在把它splay到根以后,i 结点只能sp ...

  3. 洛谷 P4402 BZOJ1552 / 3506 [Cerc2007]robotic sort 机械排序

    FHQ_Treap 太神辣 蒟蒻初学FHQ_Treap,于是来到了这道略显板子的题目 因为Treap既满足BST的性质,又满足Heap的性质,所以,对于这道题目,我们可以将以往随机出的额外权值转化为每 ...

  4. [BZOJ1552][Cerc2007]robotic sort

    [BZOJ1552][Cerc2007]robotic sort 试题描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N个用空格隔开的正整数 ...

  5. HDU1890 Robotic Sort[splay 序列]

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

  6. 【BZOJ-1552&3506】robotic sort&排序机械臂 Splay

    1552: [Cerc2007]robotic sort Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 806  Solved: 329[Submit][ ...

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

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

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

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

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

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

随机推荐

  1. centos7 host修改

    首先要说明,hostname和hosts文件没有必然联系,有不明白的同学可以先自行查阅资料了解hostname和hosts文件的关系.这里简要说明一下. hosts文件是dns服务的前身,网络刚开始出 ...

  2. Linux简单口令

    创建文件1.touch2.echo "">>file_name3.vim 文件名创建文件夹1.mkdir -p /abc/cc/bbb删除文件rm -f 文件删除文件夹 ...

  3. python 区块链程序

    python 区块链程序 学习了:https://mp.weixin.qq.com/s?__biz=MzAxODcyNjEzNQ==&mid=2247484921&idx=1& ...

  4. 教程 | 使用Sqoop从MySQL导入数据到Hive和HBase

    基础环境 sqoop:sqoop-1.4.5+cdh5.3.6+78, hive:hive-0.13.1+cdh5.3.6+397, hbase:hbase-0.98.6+cdh5.3.6+115 S ...

  5. 改變iTunes備份路徑

    *** 在任意分區建立文件夾用來移動iTunes原有備份 *** 例如:move"c:\user\vhd\appdata\roaming\apple computer"全部到&qu ...

  6. UVa 1531 - Problem Bee

    题目:如图所看到的的蜂巢型的图中.蜜蜂想从A点飞到B点,假设A与B不在同一个正六边形中, 则它先飞到A的中心.每次飞到相邻格子的中心,最后飞到B的中心,再飞到B点: 假设在一个格子中.直接飞过去就可以 ...

  7. 86. LotusScript中的数组函数

    R6对LotusScript有一些改进和增强,自那之后.Notes对象的接口时有补充和更新,但语言本身没有变化.那些改进就包括添加诸如ArrayGetIndex.ArrayUnique的实用函数. 但 ...

  8. 关于函数return的一些理解与小实例

    先看代码: function example (){ var index=1; return {//像这种加个大括号的就是返回一个对象了,而不仅仅是一个值 index, net:function(){ ...

  9. 99_leetcode_Best Time to Buy and sell Stock

    Say you have an array for which the ith element is the price of a given stock on day i. If you were ...

  10. Keys.BACKSPACE Keys.SPACE

    browser.find_element_by_xpath(xp_newpage).send_keys(Keys.SPACE)browser.find_element_by_xpath(xp_newp ...