洛谷 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 题意一样 , 双倍经 ...
随机推荐
- UnicodeDecodeError:'ascii' codec can't decode byte 0xe5 in position 89: ordinal not in range(128)
环境python2,在出现该错误的python文件,增加: import sys reload(sys) sys.setdefaultencoding('utf8') 重新运行,不再报错
- Python+Selenium - windows安全中心的弹窗(账号登录)
当出现如下图所示的 Windows安全中心弹窗,需要输入用户名和密码时 如何用Python+selenium跳过这个登录. 步骤: 1.在注册表中三个位置各添加两个东西:iexplore.exe 和 ...
- 永远的Ace 实验五 团队作业2:XXX企业设施设备云上资料室
项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/2018CST/ 这个作业要求链接 https://www.cnblogs.com/nwnu-da ...
- 华为计算平台MDC810发布量产
华为计算平台MDC810发布量产 塞力斯的发布会刚刚结束,会上塞力斯SF5自由远征版也确实让人眼前一亮. 全球首款4S级加速能力.1000+km续航新能源作为这款车的卖点. 续航1000+km成了最近 ...
- CVPR2020论文介绍: 3D 目标检测高效算法
CVPR2020论文介绍: 3D 目标检测高效算法 CVPR 2020: Structure Aware Single-Stage 3D Object Detection from Point Clo ...
- Camera Calibration 相机标定
Camera Calibration 相机标定 一.相机标定方法 在opencv中提供了一组函数用于实现相机的标定,标定返回的值包括:相机内参矩阵(fx fy xc yc).相机外参矩阵(R t)以及 ...
- AI芯片加速图像识别
AI芯片加速图像识别 AI chip accelerates image recognition 法国研究机构CEA-Leti和LIST在2020年VLSI研讨会上展示了一种概念验证芯片,该芯片集成了 ...
- 看懂redis配置文件
看懂redis 配置文件: https://blog.csdn.net/liqingtx/article/details/60330555 redis 数据库缓存双写一致性解决方案: https:// ...
- 【VBA】日期时间
当前日期: Sub 测试() Debug.Print Date End Sub 当前时间: Sub 测试() Debug.Print Date End Sub 几月: Sub 测试() Debug.P ...
- 『无为则无心』Python基础 — 5、Python开发工具的安装与使用
目录 1.Pycharm下载 2.Pycharm安装 3.PyCharm界面介绍 4.基本使用 (1)新建Python项目 (2)编写Python代码 (3)执行代码查看结果 (4)设置PyCharm ...