[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 ...
随机推荐
- 启的服务有时候突然报错:org.xml.sax.SAXParseException: schema_reference.4
记录一下,原文地址:http://blog.csdn.net/bluishglc/article/details/7596118
- 【BZOJ3110】K大数查询(权值线段树套线段树+标记永久化,整体二分)
题意:有N个位置,M个操作.操作有两种,每次操作 如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是 ...
- PatentTips - Register file supporting transactional processing
BACKGROUND OF THE INVENTION With the rise of multi-core, multi-threaded data processing systems, a k ...
- HDU——1498 50 years, 50 colors
50 years, 50 colors Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- Ubuntu 16.04安装Ubuntu After Install工具实现常用软件批量安装
这个软件集成了常用且好用的软件,且只需要选择需要的软件之后自动安装好,不需要额外设置. 安装: sudo add-apt-repository ppa:thefanclub/ubuntu-after- ...
- Dubbo-admin无法显示Group分组信息
背景: 在首次使用Dubbo的时候.我们可能都会使用Dubbo-admin来监控服务的提供者和消费者,可是在自己的生产者成功执行的时候.在Dubbo-admin却看不到不论什么信息.假设在确保代码的正 ...
- Jenkins + SVN搭建php持续集成
目标需求 开发提交代码到SVN,jenkins在分发服务器上执行'svn update',分发服务器在把代码同步到webserver,实现持续集成 流程 配置jenkins 一.jenkins所需插件 ...
- jQuery异步框架探究1:jQuery._Deferred方法
jQuery异步框架应用于jQuery数据缓存模块.jQuery ajax模块.jQuery事件绑定模块等多个模块,是jQuery的基础功能之中的一个.实际上jQuery实现的异步回调机制能够看做ja ...
- 1451 - Average 高速求平均值
怎样高速求取一段区间的平均值 用前缀的思想来看 很easy 可是 本题题意要求的是 大于等于一段长度的区间的平均值的最大值 并且给出的数据范围非常大 O(n*L)的直白比較算法 用于解决此问题不合适 ...
- Redis源代码分析(六)--- ziplist压缩列表
ziplist和之前我解析过的adlist列表名字看上去的非常像.可是作用却全然不同.之前的adlist主要针对的是普通的数据链表操作. 而今天的ziplist指的是压缩链表.为什么叫压缩链表呢.由于 ...