1 条题解
-
0
一开始看到题目的时候肯定会感觉没什么思路吧,
那么我们不妨先从简单的考虑,从 开始考虑:
我们自己把几种可能的输出
Yes
的情况全都枚举出来,找找规律(对称的只算一种):(即初始状态)
(选取 的区间;和 是对称的,先不考虑 )
(选取 的区间)
(选取 的区间)
(选取 的区间)
(选取 的区间)
(选取 的区间)
我们发现一件有趣的事情:
结论一:有 的长度为 的序列都能输出
Yes
有了这个结论,我们发现一个序列里面有很多值都可以满足了。
举个例子:
我们让 ,
那么我们可以只对相邻两个数进行操作:
(把 的区间 变为 (结论一))
(把 的区间 变为 (结论一))
同时我们还可以从后面往前搞:
(把 的区间 变为 (结论一))
但是,只剩一个 的时候我们并不能这样。
所以,我们又得到了 结论二:如果有任意一个子序列输出
Yes
,那么肯定输出Yes
,否则肯定输出No
和 结论三:如果一个序列有 ,输出Yes
那么我们现在就要寻找这个子序列了(结论二)。
我们已经把它变成 了,那么中间的 它肯定还要继续变,因为我们目前操作后这个序列里有 (最后会至少剩下一个 ),所以 ,那么目前这个序列的 肯定是 ,同时我们还能得到目前这个序列有 的数,且没有 这个数( 的定义),那么,我们对它进行一次操作,那么变化后它就会有 的数,且没有 的数,也没有 这个数。
那么我们如何找到这个子序列呢?如果暴力枚举每个区间,时间复杂度 ,无法通过此题。
那么如何优化呢?我们可以先枚举 的值,可以发现一共只有 个数,所以 不超过 ,接下来,如何 找到这个序列呢?
我们想到如果出现 或者 的值,我们肯定不要选它,其他的肯定选得越多越好,可以用一个数组维护一个数是否出现,但是如果超过 ,就不记录(因为它肯定不会对答案产生影响)。然而,我们发现清空这个数组就变成 的了,时间复杂度依旧 。
既然清空慢,那么我们优化它就可以了,那么怎么优化呢?
还记得线段树的 lazy-tag 吗?现在每个 的值都有一个类似 lazy-tag 的东西,每一次清空,相当于用 lazy-tag 记录一下。
现在,我们可以用一个变量记录整个数组被清空的次数,再用一个数组记录每个元素被清空的次数,如果我们要清空,那么把整个数组被清空的次数加 ,再要用到这个数的时候,先看该元素被清空的次数是否等于整个数组被清空的次数,如果小于,那么把被清空的次数改为整个数组被清空的次数,再把这个值归零即可。
现在清空也变成 的了,总时间复杂度 .
信息
- ID
- 864
- 时间
- 200ms
- 内存
- 32MiB
- 难度
- 6
- 标签
- (无)
- 递交数
- 41
- 已通过
- 3
- 上传者