洛谷P3165 [CQOI2014]排序机械臂
题目描述
为了把工厂中高低不等的物品按从低到高排好序,工程师发明了一种排序机械臂。它遵循一个简单的排序规则,第一次操作找到摄低的物品的位置P1,并把左起第一个至P1间的物品反序;第二次找到第二低的物品的位置P2,并把左起第二个至P2间的物品反序...最终所有的物品都会被排好序。
上图给出_个示例,第_次操作前,菝低的物品在位置4,于是把第1至4的物品反序;第二次操作前,第二低的物品在位罝6,于是把第2至6的物品反序...
你的任务便是编写一个程序,确定一个操作序列,即每次操作前第i低的物品所在位置Pi,以便机械臂工作。需要注意的是,如果有高度相同的物品,必须保证排序后它们的相对位置关系与初始时相同。
输入输出格式
输入格式:
第一行包含正整数n,表示需要排序的物品数星。
第二行包含n个空格分隔的整数ai,表示每个物品的高度。
输出格式:
输出一行包含n个空格分隔的整数Pi。
输入输出样例
输入样例#1: 复制
6
3 4 5 1 6 2
输出样例#1: 复制
4 6 4 5 6 6
好变态的题啊。
我们可以发现一个很显然的规律:
第\(i-1\)小的数一定不可能在第\(i\)次查询的区间里
那么我们可以维护一下最小值,对于每次询问,在区间内找到最小值
然后打上标记就好
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=1e5+10;
const int maxn=0x7fffff;
const int INF=0x7fffffff;
#define ls tree[x].ch[0]
#define rs tree[x].ch[1]
inline char nc()
{
static char buf[MAXN],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
char c=nc();int x=0,f=1;
while(c<'0'||c>'9'){c=nc();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();}
return x*f;
}
int n,m;
struct Q
{
int val,pos;
}a[MAXN];
struct node
{
int tot,fa,ch[2],mn,mnpos,v;
bool rev;
}tree[MAXN];
int tot,point;
int root;
int PosL,PosR;
inline void connect(int x,int fa,bool how)
{
tree[x].fa=fa;
tree[fa].ch[how]=x;
}
inline void update(int k)
{
if(!k) return ;
tree[k].tot=tree[tree[k].ch[0]].tot+tree[tree[k].ch[1]].tot+1;
tree[k].mn=tree[k].v; tree[k].mnpos=k;
if(tree[k].ch[0]&&tree[tree[k].ch[0]].mn<tree[k].mn) tree[k].mn=tree[tree[k].ch[0]].mn,tree[k].mnpos=tree[tree[k].ch[0]].mnpos;
if(tree[k].ch[1]&&tree[tree[k].ch[1]].mn<tree[k].mn) tree[k].mn=tree[tree[k].ch[1]].mn,tree[k].mnpos=tree[tree[k].ch[1]].mnpos;
}
inline int BuildTree(int l,int r)
{
if(l>r) return 0;
int mid=(l+r)>>1;
if(l!=r)
{
connect(BuildTree(l,mid-1),mid,0);
connect(BuildTree(mid+1,r),mid,1);
}
tree[mid].rev=0;
tree[mid].mn=a[mid].val;
tree[mid].v=a[mid].val;
tree[mid].mnpos=mid;
update(mid);
return mid;
}
inline bool ident(int x)
{
return tree[tree[x].fa].ch[1]==x;
}
inline void pushdown(int x)
{
if(tree[x].rev)
{
swap(tree[x].ch[0],tree[x].ch[1]);
tree[tree[x].ch[0]].rev^=1;
tree[tree[x].ch[1]].rev^=1;
tree[x].rev=0;
}
}
inline void rotate(int X)
{
pushdown(tree[X].fa);pushdown(X);
int Y=tree[X].fa;
if(Y==root) root=X;
int R=tree[Y].fa;
bool Yson=ident(X);
bool Rson=ident(Y);
int B=tree[X].ch[Yson^1];
connect(B,Y,Yson);
connect(Y,X,Yson^1);
connect(X,R,Rson);
update(Y);update(X);
}
inline void splay(int x,int to)
{
to=tree[to].fa;
while(tree[x].fa!=to)
{
if(tree[tree[x].fa].fa==to) rotate(x);
else if(ident(x)==ident(tree[x].fa)) rotate(tree[x].fa),rotate(x);
else rotate(x),rotate(x);
}
update(x);
}
int find(int x, int rk)
{
pushdown(x);//标记下传
if(tree[ls].tot+1==rk) return x;
else if(tree[ls].tot >= rk) return find(ls, rk);
else return find(rs, rk-tree[ls].tot-1);
}
const int comp(const Q a,const Q b)
{
return a.val<b.val||(a.val==b.val&&a.pos<b.pos);
}
const int comp2(const Q a,const Q b)
{
return a.pos<b.pos;
}
int QueryMin(int l,int r)
{
int x1=find(root,l);
int x2=find(root,r+2);
splay(x1,root);
splay(x2,tree[x1].ch[1]);
return tree[ tree[x2].ch[0] ].mnpos;
}
inline void rever(int l,int r)
{
int x1=find(root,l),x2=find(root,r+2);
splay(x1,root);splay(x2,tree[x1].ch[1]);
tree[tree[x2].ch[0]].rev^=1;
}
int main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
#else
#endif
int n=read();
a[1].val=a[n+2].val=INF;
for(int i=2;i<=n+1;i++) a[i].val=read(),a[i].pos=i;
sort(a+2,a+n+2,comp);
for(int i=2;i<=n+1;i++) a[i].val=i-1;
sort(a+2,a+n+2,comp2);
//for(int i=1;i<=n+2;i++) printf("%d ",a[i].pos);printf("\n");
BuildTree(1,n+2);
root=(n+3)>>1;
for(int i=1;i<=n;i++)
{
int x=QueryMin(i,n);
splay(x,root);
int out=tree[tree[x].ch[0]].tot;
rever(i,out);
printf("%d ",out);
}
}
洛谷P3165 [CQOI2014]排序机械臂的更多相关文章
- [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 ...
- P3165 [CQOI2014]排序机械臂
题目描述 为了把工厂中高低不等的物品按从低到高排好序,工程师发明了一种排序机械臂.它遵循一个简单的排序规则,第一次操作找到高度最低的物品的位置 P1P_1P1 ,并把左起第一个物品至 P1P_1P1 ...
- Luogu P3165 [CQOI2014]排序机械臂
先讲一下和这题一起四倍经验的题: Luogu P4402 [Cerc2007]robotic sort 机械排序 SP2059 CERC07S - Robotic Sort UVA1402 Robot ...
- 【BZOJ3506】[CQOI2014] 排序机械臂(Splay)
点此看题面 大致题意: 给你\(n\)个数.第一次找到最小值所在位置\(P_1\),翻转\([1,P_1]\),第二次找到剩余数中最小值所在位置\(P_2\),翻转\([2,P_2]\),以此类推.求 ...
- bzoj3506 [Cqoi2014]排序机械臂
bzoj3506 此题是一道比较简单的spaly题目. 用splay维护序列,将每个点排到对应的位置之后删除,这样比较容易区间翻转. 我的指针写法在洛谷上AC了,但在bzoj上RE. #include ...
- 【洛谷 P3165】 [CQOI2014]排序机械臂 (Splay)
题目链接 debug了\(N\)天没debug出来,原来是找后继的时候没有pushdown... 众所周知,,Splay中每个编号对应的节点的值是永远不会变的,因为所有旋转.翻转操作改变的都是父节点和 ...
- BZOJ1552[Cerc2007]robotic sort&BZOJ3506[Cqoi2014]排序机械臂——非旋转treap
题目描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000. 第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号. 输出 输出共一行,N个用空格隔开 ...
- BZOJ3506/1502 [CQOI2014]排序机械臂
传送门 依然是一道splay的区间操作,需要注意的是要把下标离散化后来表示splay的节点,我不知道怎么搞所以索性弄了个$ValuetoNode$,看样子没什么问题, 感觉他那个传下标的方法太暴力了. ...
随机推荐
- impala jdbc4的group by语句的bug,加上limit没错
这里用的ImpalaJDBC4.jar SELECT field1 alias1 FROM table1 where field1 ='xxxx' group by alias1 这句话impala会 ...
- 每天一个linux命令(九月)
2014-09-02 top 实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器 命令參数: -b 批处理 -c 显示完整的治命令 -I 忽略失效过程 -s 保密模式 -S 累积模 ...
- java调用com组件将office文件转换成pdf
在非常多企业级应用中都涉及到将office图片转换成pdf进行保存或者公布的场景,由于pdf格式的文档方便进行加密和权限控制(类似于百度文库).总结起来眼下将office文件转换 成pdf的方法主要有 ...
- 关于android studio几种常见的错误解决
我也是从ec转到as的,没办法,大势所趋嘛,然而,在使用as的过程中遇到了非常多匪夷所思的错误,如今就说一下今天我遇到的这个错误. 美工妹子给了我一张图片,用来当做button的背景图,当然,这个图也 ...
- Python3小白初体验
三层循环嵌套,以后优化 data = { "北京":{ "a":{ ", " }, "b":{ ", &quo ...
- [工具] UltraEdit使用技巧汇总
ltraEdit是一套功能强大的文本编辑器,可以编辑文本.十六进制.ASCII码,可以取代记事本,内建英文单字检查.C++及VB指令突显,可同时编辑多个文件,而且即使开启很大的文件速度也不会慢.说到编 ...
- 打印机共享为什么老是出现“操作无法完成(错误 0X00000709)。再次检查打印机名称、并确保打印机连接网络
这个情况应该是访问IP连接打印机才会出现的.解决办法:不使用IP访问,使用网上邻居找计算机名称再连接打印机即可. ------------------------------------------- ...
- 紫书 习题 10-16 UVa 1647 (高精度+递推)
这道题我已经推出00和1过两步变成00了,可我没有继续做下去-- 后来看了博客发现自己已经做了90%了-- 可惜了,以后不要轻易放弃. 1的个数有个规律,就是每次都乘以2,因为0和1下一步都会变出1 ...
- Android应用公布后的统计——百度移动统计的应用
一个App公布到各个渠道之后,我们须要採集不同渠道的一些信息,比方app在执行过程中产生的一些异常信息,app在各个android版本号的分布,以及各个app版本号的分布,各渠道的用户数,用户忠诚度等 ...
- HBase概念学习(八)开发一个类twitter系统之表设计
这边文章先将可能的需求分析一下,设计出HBase表,下一步再開始编写client代码. TwiBase系统 1.背景 为了加深HBase基本概念的学习,參考HBase实战这本书实际动手做了这个样例. ...