原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3506
洛谷链接:https://www.luogu.org/problemnew/show/P3165

排序机械臂

题目描述

为了把工厂中高低不等的物品按从低到高排好序,工程师发明了一种排序机械臂。它遵循一个简单的排序规则,第一次操作找到摄低的物品的位置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

说明

N<=100000

Pi<=10710710^{7}

题解

非常板的Splay,只需要区间翻转和查找第K个,对于序列之王Splay简直小菜一碟好吗??第K个可以预处理,只需要注意在Splay时对区间翻转标记的维护。

另外,因为物品的高度在序列中是没什么用的,更何况题目还要求高度相同的物品操作前后顺序不变,所以离散化,树中储存编号即可。

代码
#include<bits/stdc++.h>
using namespace std;
int root,tot,f,ff;
bool k;
struct node{int son[2],dad,fir,rk,sz;bool rev;node(){memset(this,0,sizeof(this));}
};
struct sd{int n,fir;bool operator < (const sd &x) const{if(n!=x.n) return n<x.n;return fir<x.fir;}
};
sd x[100005];
node tree[100005];
void up(int v)
{tree[v].sz=tree[tree[v].son[0]].sz+tree[tree[v].son[1]].sz+1;
}
void push(int v)
{if(tree[v].rev){tree[tree[v].son[0]].rev^=1;tree[tree[v].son[1]].rev^=1;swap(tree[v].son[0],tree[v].son[1]);tree[v].rev=0;}
}
void spin(int v)
{f=tree[v].dad;ff=tree[f].dad;k=(tree[f].son[1]==v);tree[ff].son[tree[ff].son[1]==f]=v;tree[v].dad=ff;tree[f].son[k]=tree[v].son[!k];tree[tree[v].son[!k]].dad=f;tree[v].son[!k]=f;tree[f].dad=v;up(f);up(v);
}
void splay(int v,int goal)
{while(tree[v].dad!=goal){f=tree[v].dad;ff=tree[f].dad;if(ff)push(ff);if(f)push(f);if(v)push(v);if(ff!=goal)((tree[ff].son[0]==f)^(tree[f].son[0]==v))?spin(v):spin(f);spin(v);}if(!goal) root=v;
}
void insert(int fir,int rk)
{int v=root;f=0;while(tree[v].fir!=fir&&v)f=v,v=tree[v].son[fir>tree[v].fir];v=++tot;if(f) tree[f].son[fir>tree[f].fir]=v;tree[v].sz=1;tree[v].fir=fir;tree[v].rk=rk;tree[v].dad=f;splay(v,0);
}
int s;
int rank(int x)
{int v=root;while(1){push(v);s=tree[v].son[0];if(x>tree[s].sz+1){x-=tree[s].sz+1;v=tree[v].son[1];}elseif(tree[s].sz>=x) v=s;else return v;}
}
int n;
void in()
{scanf("%d",&n);for(int i=1;i<=n;++i)scanf("%d",&x[i].n),x[i].fir=i;sort(x+1,x+n+1);for(int i=1;i<=n;++i)insert(x[i].fir,i);insert(-1,-1);insert(n+1,1e9+5);
}
void ac()
{int le,ri,hh;splay(1,0);hh=tree[tree[root].son[0]].sz;printf("%d",hh);le=rank(1);ri=rank(hh+2);splay(le,0);splay(ri,le);tree[tree[ri].son[0]].rev^=1;for(int i=2;i<=n;++i){splay(i,0);hh=tree[tree[root].son[0]].sz;printf(" %d",hh);if(i==n) return;ri=rank(hh+2);le=i-1;splay(le,0);splay(ri,le);tree[tree[ri].son[0]].rev^=1;}
}
int main()
{in();ac();return 0;
}

BZOJ3506 [CQOI2014]排序机械臂相关推荐

  1. [bzoj1552][Cerc2007]robotic sort[bzoj3506][Cqoi2014]排序机械臂

    非常垃圾的一道平衡树,结果被日了一天.很难受嗷嗷嗷 首先不得不说网上的题解让我这个本来就不熟悉平衡树的彩笔很难受--并不好理解. 还好Sinogi大佬非常的神,一眼就切掉了,而且用更加美妙的解法. 题 ...

  2. 【BZOJ3506】[CQOI2014] 排序机械臂(Splay)

    点此看题面 大致题意: 给你\(n\)个数.第一次找到最小值所在位置\(P_1\),翻转\([1,P_1]\),第二次找到剩余数中最小值所在位置\(P_2\),翻转\([2,P_2]\),以此类推.求 ...

  3. 【splay】BZOJ 1152 3506:[cqoi2014]排序机械臂

    BZOJ 1152 && 3506:[cqoi2014]排序机械臂 Description Input 输入共两行,第一行为一个整数N,N表示物品的个数,第二行为N个用空格隔开的正整数 ...

  4. P3165 [CQOI2014]排序机械臂

    传送门 就是说要维护一个数据结构资瓷区间反转和查询第\(K\)大,那么splay吧 我们可以把原数组按高度为第一关键字,下标为第二关键字排序,然后直接建出splay 这样的话每次第\(K\)大直接查询 ...

  5. 洛谷3165 CQOI2014 排序机械臂 splay

    题目链接 题意: 给你一个长度为nnn的序列,现在有一种对序列排序的方法:假设当前最小的前iii个已经找到了,我们找到i+1i+1i+1到nnn里面最早出现的最小值,设其出现位置为jjj,我们将区间[ ...

  6. bzoj 1552: [Cerc2007]robotic sort bzoj 3506: [Cqoi2014]排序机械臂(splay区间翻转)

    1552: [Cerc2007]robotic sort Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 1206  Solved: 460 [Submi ...

  7. 【bzoj3506】【CQOI2014】排序机械臂

    Description 有n个物品,每个物品有它的高度a[i],现在我们要采用一种神奇的方法把这n个物品排好序.第x次我们找到第x矮的物品位置p[x],并且把x到p[x]中间的物品翻转.如果有多个一样 ...

  8. python机械臂仿真_使用VTK与Python实现机械臂三维模型可视化

    三维可视化系统的建立依赖于三维图形平台, 如 OpenGL.VTK.OGRE.OSG等, 传统的方法多采用OpenGL进行底层编程,即对其特有的函数进行定量操作, 需要开发人员熟悉相关函数, 从而造成 ...

  9. 机器人抓矸石_基于机器视觉的多机械臂煤矸石分拣机器人系统研究

    工矿自动化 Industryand MineAutomation Vol. 45 No. 9 Sep.2019 第 45 卷第 9 期 2019 年 9 月 文章编号 : 1671 - 251X(20 ...

  10. 简单的机械臂设计(Splay树)

    时间限制: 2 Sec 内存限制: 32 MB 题目描述 在东秦综合楼的深处,有实验室检查各种材料的机械和电学性能.你受蔡老板所托为一个在实验室中处理样品的机器人编写软件.在传送带上有材料样本,样品有 ...

最新文章

  1. github中origin和upstream的区别(转)
  2. NDK 与 JNI 的关系
  3. SVN interrupted与already-locked 解决方法
  4. java vector 多线程_如何使用vector解决多线程问题(java)
  5. C语言字符串中运算符,c语言字符串中找到一个运算符,怎样实现运算
  6. iOS开发-retain/assign/strong/weak/copy/mutablecopy/autorelease区别
  7. magento 2 引用 css,Magento2在Phtml文件中调用显示静态块
  8. hdu 1251(字典树)
  9. Win7主题制作教程 电脑主题制作图文方法
  10. 英语听力学习方法,转自一牛人的博客
  11. VMware安装苹果虚拟机-亲测有效
  12. python之读取和写入文件
  13. 一个自动化专业的工控人自学编程之路
  14. redis实现的分布式锁为啥要设置过期时间?
  15. Hexo博客搭建以及主题使用
  16. 【Excel】用公式提取Excel单元格中的汉字
  17. phpstorm注册码 激活 授权码 License server
  18. mysql rds 定时执行_如何使用脚本自动备份阿里云rds数据库
  19. Python爬虫,爬取51job上有关大数据的招聘信息
  20. 前端项目搭建部署全流程(一):搭建React项目

热门文章

  1. Raki的读paper小记:Word2Vec
  2. 操作系统面试常问问题
  3. 北邮计算机学院 王小捷,王小捷智能科学与技术中心北京邮电大学.pdf
  4. java自动扫描不好使_Spring 自动扫描 不支持jar包 component-scan
  5. CentOS下常用配置文件和命令以及目录结构备注
  6. mysql登录出现1045错误
  7. Codeforces 1013
  8. 【HDU6051】if the starlight never fade
  9. DELPHI 对象的本质 VMT
  10. HTTP 长连接 使用场景