一点小想法

Codeforces 1550C Manhattan Subarrays

借着这道题总结一下CF解题自己的一个小套路:观察性质,套数据范围,利用性质一步步推下一个子问题的做法。

观察性质

性质1

只有一个点被完全夹在了两个点中间时,才会出现bad triples。
即出现一个点(p, q),存在点(x1, y1)与(x2, y2)使得 p 属于 [x1, x2] 且 q 属于[y1, y2]。

性质2

每次新加入的点一定是当前所有点中x最大的。于是要找到两个点,它们的x递减,y要么递增,要么递减。

性质3

由性质3即得,一个区间是bad的 iff 存在一个单调序列 len >= 3。

套数据范围想做法

想法1

数据范围是2e5。利用two pointers,设每次区间查询复杂度为x,那么总体的算法复杂度是O(nx)的。这里要求O(x) <= lgx。那么需要找到一种lgx以内的做法。
第一步先验证two pointers的可行性。
首先想到,对于任意的[l, r],如果它是good的,[l + 1, r]一定是good的,我们没有必要计算这部分,这时候让r ++即可,直到[l, r]是一个bad的区间。
当发现[l, r]开始bad的时候,不断让l ++,获得一个good区间,继续迭代。
每次发现bad区间的时候,记录上一次good的区间[l, r]。这个区间[l, r]中的任意连续子区间都是good的。
对于重叠的部分是会重复计算的,需要设置一个last_l 与 last_y 去掉重复的部分。
two pointers看来是可行的。
第二步找到一个O(lgn)以内查询一个区间LIS长度的方法。
首先,线段树是可以实现的,但是代码太难实现。
其次,想到了两种单调的数据结构,分别是单调栈和单调队列。
但是这两种数据结构能解决的问题并不适合这道题。
单调栈可以用来查询数组中每个ai左边或者右边第一个比它大或者小的数值。
单调队列可以nlgn查询一个静态数组的LIS。缺点是不能动态。
单调队列还可以用来查询滑动窗口的最大值。缺点是不能求LIS。
//复习单调栈、单调队列、线段树

想法2

归纳一般性质。
容易发现,len >= 5的子区间其LIS长度一定>=3。
问题转化成判断所有长度为3或者4的子区间是否good即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值