[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 ...
随机推荐
- centos7 host修改
首先要说明,hostname和hosts文件没有必然联系,有不明白的同学可以先自行查阅资料了解hostname和hosts文件的关系.这里简要说明一下. hosts文件是dns服务的前身,网络刚开始出 ...
- Linux简单口令
创建文件1.touch2.echo "">>file_name3.vim 文件名创建文件夹1.mkdir -p /abc/cc/bbb删除文件rm -f 文件删除文件夹 ...
- python 区块链程序
python 区块链程序 学习了:https://mp.weixin.qq.com/s?__biz=MzAxODcyNjEzNQ==&mid=2247484921&idx=1& ...
- 教程 | 使用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 ...
- 改變iTunes備份路徑
*** 在任意分區建立文件夾用來移動iTunes原有備份 *** 例如:move"c:\user\vhd\appdata\roaming\apple computer"全部到&qu ...
- UVa 1531 - Problem Bee
题目:如图所看到的的蜂巢型的图中.蜜蜂想从A点飞到B点,假设A与B不在同一个正六边形中, 则它先飞到A的中心.每次飞到相邻格子的中心,最后飞到B的中心,再飞到B点: 假设在一个格子中.直接飞过去就可以 ...
- 86. LotusScript中的数组函数
R6对LotusScript有一些改进和增强,自那之后.Notes对象的接口时有补充和更新,但语言本身没有变化.那些改进就包括添加诸如ArrayGetIndex.ArrayUnique的实用函数. 但 ...
- 关于函数return的一些理解与小实例
先看代码: function example (){ var index=1; return {//像这种加个大括号的就是返回一个对象了,而不仅仅是一个值 index, net:function(){ ...
- 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 ...
- Keys.BACKSPACE Keys.SPACE
browser.find_element_by_xpath(xp_newpage).send_keys(Keys.SPACE)browser.find_element_by_xpath(xp_newp ...