洛谷P2824-排序-线段树分裂合并+set / 二分答案+线段树

这篇博客介绍了2023年大厂机试真题中关于排序操作的两种解题方法。方法一是通过二分答案配合线段树,利用01串排序优化;方法二是结合set和动态开点权值线段树进行分裂合并。文章讨论了两种方法的时间复杂度、空间复杂度以及各自的优缺点,并提供了AC代码。
摘要由CSDN通过智能技术生成

2023大厂真题提交网址(含题解):

www.CodeFun2000.com(http://101.43.147.120/)

最近我们一直在将收集到的机试真题制作数据并搬运到自己的OJ上,供大家免费练习,体会真题难度。现在OJ已录入50+道2023年最新大厂真题,同时在不断的更新。同时,可以关注"塔子哥学算法"公众号获得每道题的题解。
在这里插入图片描述

题目大意

给你一个长度为 n n n的排列。然后给 m m m次操作。每次对一个区间升序排序/降序排序。问最后第p个位置是多少?

方法一:二分答案+线段树(思维)

核心:对数字排序太慢了。但是对01串排序却可以高效的使用线段树来实现
那么我们可以二分答案,令答案在 [ m i d , n ] [mid,n] [mid,n]区间里。将值域在该区间里的数变为1,其他变为0。那么线段树模拟一遍,然后 c h e c k check check一下位置p是否为1.这么二分即可。

复杂度: O ( m l o g n l o g n ) O(mlognlogn) O(mlognlogn)

方法二:set+动态开点权值线段树分裂合并

核心:
1.我们用一个权值线段树来维护/表征 一个有序的区间.那么最开始就有 n n n个有序段.
2.每次排序操作,等同于将若干个有序区间合并.而且最多可能会在左右端点处将两个有序区间分裂开.
3.我们规定将一个有序区间(一个权值线段树)的根记到该区间的最左位置。

例如: [4 5 6] [3 2 1] [7]

那么整个序列有三颗线段树,三个根分别为{1,4,7} (数值代表下标).

4.具体操作示范:
如果现在我需要重新升序排序区间[2,5]

1.那么先快速找到下标2的根:1,再快速找到下标5的根:4
2.将树rt[1]和rt[4]分裂成: [4] [5 6] [3 2] [1][7]
3.将树rt[1]到rt[4]之间所有根合并到一棵权值线段树上:
[4][2 3 5 6][1][7]

PS:
1.上述找根过程可以使用set+二分来优化
2.由于权值线段树本身有序,所以使用一个标记来表征该有序区间是升序还是降序.

复杂度

时间复杂度:
1步骤的复杂度为: O ( l o g n ) O(logn) O(logn)
2步骤的复杂度为: O ( l o g n ) O(logn) O(logn)
3步骤的复杂度为:
就是将所有树合并成一棵树的复杂度?,大概为 m l o g n mlogn mlogn

所以总复杂度为: O ( ( n + m ) l o g n ) O((n+m)logn) O((n+m)logn)?

空间复杂度:

方法对比

方法一:
好处:
可以解决有值重复的问题
坏处:
无法查询最终数组状态,只能查询某个位置

方法二:
坏处:不支持值重复.
好处:可以高效模拟整个过程.可以获得数组最终状态.

PS:set如果换成线段树维护,好像可以支持在线查询区间和等性质&#

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值