P3165 [CQOI2014]排序机械臂
题目描述
为了把工厂中高低不等的物品按从低到高排好序,工程师发明了一种排序机械臂。它遵循一个简单的排序规则,第一次操作找到高度最低的物品的位置 P1P_1P1 ,并把左起第一个物品至 P1P_1P1 间的物品 (即区间 [1,P1][1,P_1][1,P1] 间的物品) 反序;第二次找到第二低的物品的位置 P2P_2P2 ,并把左起第二个至 P2P_2P2 间的物品 (即区间 [2,P2][2,P_2][2,P2] 间的物品) 反序……最终所有的物品都会被排好序。

上图给出有六个物品的示例,第一次操作前,高度最低的物品在位置 444 ,于是把第一至第四的物品反序;第二次操作前,第二低的物品在位罝六,于是把第二至六的物品反序……
你的任务便是编写一个程序,确定一个操作序列,即每次操作前第 iii 低的物品所在位置 PiP_iPi ,以便机械臂工作。需要注意的是,如果有高度相同的物品,必须保证排序后它们的相对位置关系与初始时相同。
输入输出格式
输入格式:
第一行包含正整数n,表示需要排序的物品数星。
第二行包含n个空格分隔的整数PiP_iPi,表示每个物品的高度。
输出格式:
输出一行包含n个空格分隔的整数Pi。
输入输出样例
6
3 4 5 1 6 2
4 6 4 5 6 6
说明
N<=100000
Pi<=10^7
Solution:
本题既然区间反转,那么Splay裸题。
首先对高度排序得到操作的顺序,再对初始位置中序遍历建树。
对于每次操作的原位置,将其旋到根,答案(新的位置)就是其左子树的大小,然后因为它的前趋之前的数已经位置固定,那么只要把它和后继所在的子树翻转,所以把前趋旋转到根,再把后继旋转到根的右儿子,打上懒惰标记就好了。
注意,每次在splay改变树的形态时下放标记,用栈存下一条链上的节点并下放,在查排名的时候也得下放标记。
代码:
/*Code by 520 -- 9.20*/
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
#define son(x) (x==ch[fa[x]][1])
using namespace std;
const int N=;
int n,ans,stk[N],top;
int root,cnt,ch[N][],siz[N],lazy[N],fa[N];
struct node{
int v,id;
bool operator < (const node &a) const {return v==a.v?id<a.id:v<a.v;}
}a[N]; int gi(){
int a=;char x=getchar();bool f=;
while((x<''||x>'')&&x!='-') x=getchar();
if(x=='-') x=getchar(),f=;
while(x>=''&&x<='') a=(a<<)+(a<<)+(x^),x=getchar();
return f?-a:a;
} il void pushup(int rt){siz[rt]=siz[ch[rt][]]+siz[ch[rt][]]+;} il void pushdown(int rt){
if(lazy[rt]){
lazy[ch[rt][]]^=,lazy[ch[rt][]]^=;
swap(ch[rt][],ch[rt][]),lazy[rt]=;
}
} il void rotate(int x){
int y=fa[x],z=fa[y],b=son(x),c=son(y),a=ch[x][!b];
z?ch[z][c]=x:root=x; fa[x]=z;
if(a) fa[a]=y; ch[y][b]=a;
fa[y]=x,ch[x][!b]=y;
pushup(y),pushup(x);
} il void splay(int x,int i){
int tp=x;top=;
while(fa[tp]!=i) stk[++top]=tp,tp=fa[tp];
while(top) pushdown(stk[top--]);
while(fa[x]!=i){
int y=fa[x],z=fa[y];
if(z==i) rotate(x);
else {
if(son(x)==son(y)) rotate(y),rotate(x);
else rotate(x),rotate(x);
}
}
} int build(int l,int r,int lst){
int rt=l+r>>;
fa[rt]=lst,siz[rt]=;
if(l<rt) ch[rt][]=build(l,rt-,rt);
if(r>rt) ch[rt][]=build(rt+,r,rt);
pushup(rt);return rt;
} il int getrank(int x){
int rt=root;
while(){
pushdown(rt);
if(siz[ch[rt][]]>=x&&ch[rt][]) rt=ch[rt][];
else {
x-=siz[ch[rt][]]+;
if(!x) return rt;
rt=ch[rt][];
}
}
} int main(){
n=gi();
a[]={-0x7fffffff,},a[n+]={0x7fffffff,n+};
For(i,,n+) a[i].v=gi(),a[i].id=i;
sort(a+,a+n+);
root=build(,n+,);
For(i,,n) {
splay(a[i].id,);
ans=siz[ch[root][]]+;
printf("%d ",ans-);
int pre=getrank(i-),suc=getrank(ans+);
splay(pre,),splay(suc,pre);
lazy[ch[ch[root][]][]]^=;
}
printf("%d",n);
return ;
}
P3165 [CQOI2014]排序机械臂的更多相关文章
- 洛谷P3165 [CQOI2014]排序机械臂
题目描述 为了把工厂中高低不等的物品按从低到高排好序,工程师发明了一种排序机械臂.它遵循一个简单的排序规则,第一次操作找到摄低的物品的位置P1,并把左起第一个至P1间的物品反序:第二次找到第二低的物品 ...
- Luogu P3165 [CQOI2014]排序机械臂
先讲一下和这题一起四倍经验的题: Luogu P4402 [Cerc2007]robotic sort 机械排序 SP2059 CERC07S - Robotic Sort UVA1402 Robot ...
- [UVA1402]Robotic Sort;[SP2059]CERC07S - Robotic Sort([洛谷P3165][CQOI2014]排序机械臂;[洛谷P4402][Cerc2007]robotic sort 机械排序)
题目大意:一串数字,使用如下方式排序: 先找到最小的数的位置$P_1$,将区间$[1,P_1]$反转,再找到第二小的数的位置$P_2$,将区间$[2,P_2]$反转,知道排序完成.输出每次操作的$P_ ...
- 洛谷P3165 [CQOI2014]排序机械臂 Splay维护区间最小值
可以将高度定义为小数,这样就完美的解决了优先级的问题. Code: #include<cstdio> #include<algorithm> #include<cstri ...
- 【BZOJ3506】[CQOI2014] 排序机械臂(Splay)
点此看题面 大致题意: 给你\(n\)个数.第一次找到最小值所在位置\(P_1\),翻转\([1,P_1]\),第二次找到剩余数中最小值所在位置\(P_2\),翻转\([2,P_2]\),以此类推.求 ...
- 【洛谷 P3165】 [CQOI2014]排序机械臂 (Splay)
题目链接 debug了\(N\)天没debug出来,原来是找后继的时候没有pushdown... 众所周知,,Splay中每个编号对应的节点的值是永远不会变的,因为所有旋转.翻转操作改变的都是父节点和 ...
- BZOJ1552[Cerc2007]robotic sort&BZOJ3506[Cqoi2014]排序机械臂——非旋转treap
题目描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000. 第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号. 输出 输出共一行,N个用空格隔开 ...
- bzoj3506 [Cqoi2014]排序机械臂
bzoj3506 此题是一道比较简单的spaly题目. 用splay维护序列,将每个点排到对应的位置之后删除,这样比较容易区间翻转. 我的指针写法在洛谷上AC了,但在bzoj上RE. #include ...
- BZOJ3506/1502 [CQOI2014]排序机械臂
传送门 依然是一道splay的区间操作,需要注意的是要把下标离散化后来表示splay的节点,我不知道怎么搞所以索性弄了个$ValuetoNode$,看样子没什么问题, 感觉他那个传下标的方法太暴力了. ...
随机推荐
- 干货分享:五大最适合学习AI开发的编程语言
AI(人工智能)为应用开发者开创了一个全新的可能性.通过利用机器学习或深度学习,您可以生成更好的用户配置文件.个性化设置和推荐,或者整合更智能的搜索.语音界面或智能助手,或者以其他数种方式改进您的应用 ...
- x5webview 自定义全屏界面
集成X5WEBVIEW可以选择全屏模式为标准全屏还是x5全屏,而不设置默认为false. 首先看看标准全屏的基本设置, if (webView.getX5WebViewExtension() != n ...
- lua编程之协程介绍
一,lua协程简介 协程(coroutine),意思就是协作的例程,最早由Melvin Conway在1963年提出并实现.跟主流程序语言中的线程不一样,线程属于侵入式组件,线程实现的系统称之为抢占式 ...
- [PLC]ST语言二:LDP_LDF_ANDP_ANDF_ORP_ORF
一:LDP_LDF_ANDP_ANDF_ORP_ORF基本指令 说明:简单的顺控指令不做其他说明. 控制要求:无 编程梯形图: 结构化编程ST语言: (*LDP(EN,s)/ORP(EN,S)*) M ...
- Python+Selenium UI自动化测试环境搭建及使用
一什么是Selenium ? Selenium 是一个浏览器自动化测试框架,它主要用于web应用程序的自动化测试,其主要特点如下:开源.免费:多平台.浏览器.多语言支持:对web页面有良好的支持:AP ...
- Controller层@PathVariable使用
@PathVariable 映射 URL 绑定的占位符 带占位符的 URL 是 Spring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义通过 @Pa ...
- Netty源码分析第3章(客户端接入流程)---->第3节: NioSocketChannel的创建
Netty源码分析第三章: 客户端接入流程 第三节: NioSocketChannel的创建 回到上一小节的read()方法: public void read() { //必须是NioEventLo ...
- 如何利用京东云的对象存储(OSS)上传下载文件
作者:刘冀 在公有云厂商里都有对象存储,京东云也不例外,而且也兼容S3的标准因此可以利用相关的工具去上传下载文件,本文主要记录一下利用CloudBerry Explorer for Amazon S3 ...
- swoole中退出、异常与错误的处理笔记
关于PHP这方面的知识 可以看 https://www.cnblogs.com/zyf-zhaoyafei/p/6928149.html 进行补课 然后下面记录一下使用swoole的时候需要注意的地方 ...
- js弹出框 -搜索
警告框alert() alert是警告框,只有一个按钮“确定”无返回值,警告框经常用于确保用户可以得到某些信息.当警告框出现后,用户需要点击确定按钮才能继续进行操作.语法:alert("文本 ...