洛谷P3165 [CQOI2014]排序机械臂
时间:2022-05-08
本文章向大家介绍洛谷P3165 [CQOI2014]排序机械臂,主要内容包括题目描述、输入输出格式、输出格式:、输入输出样例、输出样例#1:、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
题目描述
为了把工厂中高低不等的物品按从低到高排好序,工程师发明了一种排序机械臂。它遵循一个简单的排序规则,第一次操作找到摄低的物品的位置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);
}
}
- 挑战数据结构与算法面试题——80题全解析(三)
- 巧用rowid简化sql查询(r2笔记47天)
- 算法类面试题解析——美团2016校招:棋子翻转
- 算法类面试题解析——美团2016校招:最大差值
- 用Python进行机器学习小案例
- 启用ODM极速调优IO (r2笔记66天)
- 通过addm分析io问题(r2笔记64天)
- python爬虫+R数据可视化 实例
- 梯度下降优化算法综述
- 关于oracle后台启用的schedule job(r2笔记65天)
- 数据结构和算法——二叉树
- 【专业技术】谷歌浏览器实现Javascript扩展
- 数据结构和算法——二叉排序树
- 通过shell脚本生成查询表数据的sql (r2笔记63天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 3分钟短文:胆儿真肥!Laravel在命令行问用户要数据!
- 实战矿马:数据异常牵出的挖矿木马(.systemd-service.sh)
- leetcode之两个相同字符之间的最长子字符串
- 面试阿里被P8质问:ConcurrentHashMap真的线程安全吗?
- 腾讯云TKE-搭建prometheus监控(二)
- Qt音视频开发41-人脸识别嵌入式
- 浅析Android Studio 3.0 升级各种坑(推荐)
- Android EasyPermissions官方库高效处理权限相关教程
- 关于Android 6.0权限的动态适配详解
- 详解android 人脸检测你一定会遇到的坑
- Android实战RecyclerView头部尾部添加方法示例
- android实现多线程断点续传功能
- Android 8.0 中如何实现视频通话的画中画模式的示例
- Android7.0开发实现Launcher3去掉应用抽屉的方法详解
- Android利用Paint自定义View实现进度条控件方法示例