洛谷 P4402 BZOJ1552 / 3506 [Cerc2007]robotic sort 机械排序
FHQ_Treap 太神辣
蒟蒻初学FHQ_Treap,于是来到了这道略显板子的题目
因为Treap既满足BST的性质,又满足Heap的性质,所以,对于这道题目,我们可以将以往随机出的额外权值转化为每一个位置的高度,这样我们就可以利用小根堆的性质,甚至连\(Split\)操作都可以省略掉,就可以AC这道题目
步骤:
1.首先找到现在的根节点,即当前高度最低的位置
2.根据Treap的性质,我们只需要将其左子树打一个反转的标记,然后将根节点删除,将其左右两个子树合并,那么,新的子节点就是我们接下来需要的第2小高度的位置
3.重复1,2操作,这个题目就完结撒花辣!!
但是高度有可能是相同的,题目中又要求取靠前的那一个,于是我们将所有的数乘上n,再加上i,这样就可以有效避免这一个问题。
愿望总是美好的
[CQOI2014]排序机械臂愉快的过掉了,但另外一道相同的题目却过不了(robotic sort)。然后,有dalao指出,这样的做法,只要数据是单调的,就会被卡成\(O(n^2)\)
于是,通过查阅资料,我们可以使用一种神奇的方法——笛卡尔树,这样就可以有效避免这个问题。
对于\(Treap\)来说,我们可以将每一个节点的信息简化为一个二元组\((val,rand)\),意义一看便知
我们按照val的顺序进行插入,而在本题中,val即初始位置1~n,所以不用重新排序。
我们可以维护一个单调栈,从而有效解决这个问题。
对于每一个节点,我们将栈中大于当前节点rand值的节点全部弹出,将他们挂在当前节点的左儿子上,然后再把连同当前节点一起的这一棵树挂在弹完所有值之后的栈顶节点的右儿子上,这样就可以构建出一颗相对平衡的Treap。
用通俗的话讲,对于当前节点u,我们只考虑将其放在最右边的这一条链上,如果他比所有节点的rand值都大,那么当然顺理成章的放在最右边,如果没有,我们就考虑同时维护BST与Heap的性质,于是就有了我们上面的做法。
贴代码啦~
//短短70行解决战斗
#include<bits/stdc++.h>
using namespace std;
const long long maxn=5e5+10;
long long inline read()
{
long long x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
long long son[maxn][2],val[maxn],rnd[maxn],siz[maxn],cnt,rt,tag[maxn];
inline void upd(long long t){siz[t]=siz[son[t][0]]+siz[son[t][1]]+1;}
inline void down(long long x)
{
if(tag[x])
{
swap(son[x][0],son[x][1]);
if(son[x][0]) tag[son[x][0]]^=1;
if(son[x][1]) tag[son[x][1]]^=1;
tag[x]=0;
}
}
inline long long init(long long x,long long qaq)
{
++cnt,val[cnt]=x,siz[cnt]=1,rnd[cnt]=qaq;
return cnt;
}
inline long long merge(long long x,long long y)
{
if(!x||!y) return x+y;
if(rnd[x]<rnd[y])
{
down(x),son[x][1]=merge(son[x][1],y),upd(x);
return x;
}
else
{
down(y),son[y][0]=merge(x,son[y][0]),upd(y);
return y;
}
}
struct cc{
long long num,id;
}a[maxn];
int main()
{
srand(time(0));
long long opt,n,m,l,r,x,y,z;
n=read();
stack<int> q;
for(int i=1;i<=n;++i)
{
scanf("%lld",&rnd[i]),rnd[i]=rnd[i]*n+i,val[i]=i,siz[i]=1;
while((!q.empty())&&rnd[i]<rnd[q.top()])
son[i][0]=q.top(),q.pop(),upd(son[i][0]);
if(!q.empty()) son[q.top()][1]=i;
q.push(i);
}
while(!q.empty()) rt=q.top(),upd(q.top()),q.pop();
for(int i=1;i<=n;++i)
{
down(rt);
printf("%lld ",siz[son[rt][0]]+i);
l=son[rt][0],r=son[rt][1];
son[rt][0]=son[rt][1]=0;
tag[l]^=1;
rt=merge(l,r);
}
printf("\n");
return 0;
}
洛谷 P4402 BZOJ1552 / 3506 [Cerc2007]robotic sort 机械排序的更多相关文章
- [UVA1402]Robotic Sort;[SP2059]CERC07S - Robotic Sort([洛谷P3165][CQOI2014]排序机械臂;[洛谷P4402][Cerc2007]robotic sort 机械排序)
题目大意:一串数字,使用如下方式排序: 先找到最小的数的位置$P_1$,将区间$[1,P_1]$反转,再找到第二小的数的位置$P_2$,将区间$[2,P_2]$反转,知道排序完成.输出每次操作的$P_ ...
- BZOJ1552/3506 [Cerc2007]robotic sort
Splay 与之前不同的是如果你仅仅是翻转左右区间的话可以在find里面做因为对他有影响的子树在做之前一定在他的上面从上到下搜索的过程可以把rever做了. 但这道题要求我们输出转换之前的,因此不能保 ...
- 【BZOJ1552】[Cerc2007]robotic sort Splay
[BZOJ1552][Cerc2007]robotic sort Description Input 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N ...
- 【BZOJ-1552&3506】robotic sort&排序机械臂 Splay
1552: [Cerc2007]robotic sort Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 806 Solved: 329[Submit][ ...
- 【bzoj1552】[Cerc2007]robotic sort
题目描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号. 输出 输出共一行,N个用空格隔开的 ...
- 【BZOJ】1552/3506 [Cerc2007]robotic sort
[算法]splay [题解] splay维护序列,用权值(离散化)作为编号.每次找第i小的话直接找对应编号splay即可. 但是这样splay没有下传翻转标记?直接暴力找到路径然后从根到改结点push ...
- 【bzoj1552/3506】[Cerc2007]robotic sort splay翻转,区间最值
[bzoj1552/3506][Cerc2007]robotic sort Description Input 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000. ...
- [BZOJ1552][Cerc2007]robotic sort
[BZOJ1552][Cerc2007]robotic sort 试题描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N个用空格隔开的正整数 ...
- BZOJ 1552: [Cerc2007]robotic sort( splay )
kpm大神说可以用块状链表写...但是我不会...写了个splay.... 先离散化 , 然后splay结点加个min维护最小值 , 就可以了... ( ps BZOJ 3506 题意一样 , 双倍经 ...
随机推荐
- F5 api接口开发实战手册(二)
F5 rest api 各对象使用方式详解 本篇文章介绍rest api接口下Collection.Resource.Subcollections.SubResource的各种使用方法.如果您不了解这 ...
- Oracle的Rman差异增量备份
所谓增量备份,顾名思义即是每次备份操作那些发生了"变化"的数据块.在RMAN增量备份中有两种:Differential(差异备份)和Cumulative(增量备份)方式.由于需求这 ...
- YOLO v1到YOLO v4(下)
YOLO v1到YOLO v4(下) Faster YOLO使用的是GoogleLeNet,比VGG-16快,YOLO完成一次前向过程只用8.52 billion 运算,而VGG-16要30.69bi ...
- Linux下Flash-LED的处理
Linux下Flash-LED的处理 一些LED设备提供两种模式-torch和flash.在LED子系统中,LED类(参见Linux下的LED处理)和LED Flash类,分别支持这些模式.torch ...
- Charles下载及安装破解-自己编辑
Charles下载地址 地址:https://www.charlesproxy.com/latest-release/download.do 2. Charles破解 破解地址:https://www ...
- VRRP协议的原理与配置
VRRP出现的原因: 局域网中的用户终端通常采用配置一个默认网关的形式访问外部网络,如果此时默认网关设备发生故障,将中断所有用户终端的网络访问,这很可能会给用户带来不可预计的损失. VRRP的优点: ...
- Spring Cloud10:Zipkin 服务跟踪
一.概述 为什么要有服务跟踪,分布式系统中有很多个服务在相互调用,调用关系是错综复杂的,如果这时出现了问题,我们在进行问题排查的时候,或者在优化架构的时候,工作量就比较大,这时候就需要我们能够准确的跟 ...
- 【题解】【洛谷 P1967】 货车运输
目录 洛谷 P1967 货车运输 原题 题解 思路 代码 洛谷 P1967 货车运输 原题 题面请查看洛谷 P1967 货车运输. 题解 思路 根据题面,假设我们有一个普通的图: 作图工具:Graph ...
- 不使用synchronized和lock,如何实现一个线程安全的单例
单例,大家肯定都不陌生,这是Java中很重要的一个设计模式.稍微了解一点单例的朋友也都知道实现单例是要考虑并发问题的,一般情况下,我们都会使用synchronized来保证线程安全. 那么,如果有这样 ...
- 利用 V8 深入理解 JavaScript 设计
JavaScript 代码运行 以大家开发常用的 chrome 浏览器或 Node 举例,我们的 JavaScript 代码是通过 V8 运行的.但 V8 是怎么执行代码的呢?当我们输入 const ...