其他分享
首页 > 其他分享> > [CF1367F] Flying Sort 题解

[CF1367F] Flying Sort 题解

作者:互联网

你谷 link

CF link

题解区都是一些 dp 做法,这里带来一种贪心+双指针的做法。

正片开始

题面不多做赘述,直接讲做法。

首先题面等价于选出一个单调递增的子序列,满足剩下的所有数要么比该子序列中最小的数小,要么比该子序列中最大的数大,求子序列最长长度。

发现这个东西可以 dp,但是其实也可以不 dp,直接贪心也可以。

首先一个性质,就是离散化完后选出的子序列在值域上是连续的,且子序列中出现的数除了左右端点的数,别的数只要在序列中出现了,那么所有和这个数相等的数都被必须选中了。

所以形如 \(x,x,\cdots,x,x+1,x+1,\cdots,x+1,\cdots,y-1,\cdots,y-1,y,\cdots,y\),且所有 \(a\) 满足 \(a\in[x+1,y-1]\) 都在该子序列中出现了。

利用这个性质,我们可以先将所有值离散化,然后将每个数出现的所有位置都记下来,然后枚举值的右端点的前一个,即上面的 \(y-1\),发现可以贪心地找到最靠前的 \(x+1\),满足任意 \(a\in[x+1,y-2]\) 满足 \(r_a<l_{a+1}\),即出现区间无交集。

这个显然可以双指针扫一遍得到,然后左右两边的 \(x\) 和 \(y\) 直接二分就可以了,其实也可以预处理,即在前面统计每个值出现位置时顺便记录,但二分写着更方便,且本处也不是时间复杂度瓶颈。

但是这样还会算漏一部分,就是当解形如 \(x,x,\cdots,x,x+1,\cdots,x+1\) 时,即没有中间全取的区间,两边都取得不完整,这样也可以做,就是直接枚举中间点,即第一个 \(x+1\) 的位置,然后二分前面 \(x\) 的个数和之后 \(x+1\) 的个数。

这样时间复杂度就是 \(\mathcal O\left(n\log n\right)\)。

接下来就是代码

标签:Sort,题解,可以,cdots,序列,CF1367F,该子,dp,贪心
来源: https://www.cnblogs.com/LaoMang-no-blog/p/16131199.html