[CREC2007/CQOI2014]robotic sort
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的更多相关文章
- [bzoj1552\bzoj2506][Cqoi2014]robotic sort 排序机械臂_非旋转Treap
robotic sort 排序机械臂 bzoj-1552 bzoj-2506 Cqoi-2014 题目大意:给定一个序列,让你从1到n,每次将[1,p[i]]这段区间反转,p[i]表示整个物品权值第i ...
- 【BZOJ】【1552】【Cerc2007】robotic sort / 【3506】【CQOI2014】排序机械臂
Splay 离散化+Splay维护序列…… 好吧主要说一下我做这道题遇到的几个错误点: 1.离散化 2.由于找到的这个数的位置一定是大于等于 i 的,所以其实在把它splay到根以后,i 结点只能sp ...
- 洛谷 P4402 BZOJ1552 / 3506 [Cerc2007]robotic sort 机械排序
FHQ_Treap 太神辣 蒟蒻初学FHQ_Treap,于是来到了这道略显板子的题目 因为Treap既满足BST的性质,又满足Heap的性质,所以,对于这道题目,我们可以将以往随机出的额外权值转化为每 ...
- [BZOJ1552][Cerc2007]robotic sort
[BZOJ1552][Cerc2007]robotic sort 试题描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N个用空格隔开的正整数 ...
- HDU1890 Robotic Sort[splay 序列]
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 【BZOJ-1552&3506】robotic sort&排序机械臂 Splay
1552: [Cerc2007]robotic sort Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 806 Solved: 329[Submit][ ...
- 数据结构(Splay平衡树):HDU 1890 Robotic Sort
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- BZOJ 1552: [Cerc2007]robotic sort( splay )
kpm大神说可以用块状链表写...但是我不会...写了个splay.... 先离散化 , 然后splay结点加个min维护最小值 , 就可以了... ( ps BZOJ 3506 题意一样 , 双倍经 ...
- hdu 1890 Robotic Sort(splay 区间反转+删点)
题目链接:hdu 1890 Robotic Sort 题意: 给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次. 题解: 典型的sp ...
随机推荐
- node.js 读取文件--createReadStream
createReadStream 是fs模块里面读流的一个方法 这个方法基于fs模块的,所以我们先要引进fs模块 let fs=require("fs"); createReadS ...
- Linux下汇编语言学习笔记57 ---
这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...
- 解决json_encode中文乱码
在使用json_encode之前把字符用函数urlencode()处理一下,然后再json_encode,输出结果的时候在用函数urldecode()转回来
- Layui栅格系统与后台框架布局
一.栅格布局规则: 1. 采用 layui-row 来定义行,如:<div class="layui-row"></div> 2. 采用类似 layui-c ...
- python函数值传递还是引用传递
c/c++中有值传递引用传递的区别.但是python中是值传递还是引用传递呢?首先看python中对变量的定义 "python中变量是指向某个内存的, 而内存中的内容是不可变的." ...
- "Simple Factory" vs "Factory Method" vs "Abstract Factory" vs "Reflect"
ref: http://www.cnblogs.com/zhangchenliang/p/3700820.html 1. "Simple Factory" package torv ...
- python内置全局变量
vars()查看内置全局变量 以字典方式返回内置全局变量 #!/usr/bin/env python # -*- coding:utf8 -*- print(vars()) #输出 # {'__bui ...
- IDEA启动Tomcat报错
Maven编译成功, 可是启动Tomcat报错: Application Server was not connected before run configuration stop, reason: ...
- 在Android程序中使用已有的SQLite数据库
已经将这篇文章迁移至 Code问答,你也能够到这里查看这篇文章,请多多关注我的新技术博客CodeWenDa.com 在中文搜索中,没有找到一篇比較好的关于怎样在Android应用中使用自己事先创建好的 ...
- 《深入理解Android 卷III》第四章 深入理解WindowManagerService
<深入理解Android 卷III>即将公布,作者是张大伟.此书填补了深入理解Android Framework卷中的一个主要空白.即Android Framework中和UI相关的部分. ...