目录
- @description@
- @solution@
- @accepted code@
- @details@
@description@
我们称一个序列是 k-d 的,当且仅当我们可以加入最多 k 个数,然后将序列排序,最终得到的序列是等差的且公差为 d。
给定一个序列 a,求 a 中的一个最长子区间,使得该子区间是 k-d 的。
1 ≤ n ≤ 2·10^5; 0 ≤ k ≤ 2·10^5; 0 ≤ d ≤ 10^9; -10^9 ≤ ai ≤ 10^9。
原题戳这里
@solution@
先特判 d = 0 的情况:找最长连续相同的段。
假如一个区间能够加入若干数使其满足条件,则这个区间内的所有数 mod d 应相等。其次,这个区间还应满足任意两个数互不相等。
可以求出每一个点 i 作为右端点,满足以上两个条件的左端点最远到 le[i]。
对于满足以上两个条件的区间,我们尝试去求所需要加入的数最少为多少。
求出该区间 [l, r] 的 max 与 min,则 (max - min) / d 为它的最少项数。现在已经有 r - l + 1 项,则最少需要 (max - min) / d - (r - l + 1) 项。
注意 (max - min) / d 可以写成 (max - max mod d) / d - (min - min mod d) / d。
扫描右端点,通过单调队列可以 O(n) 修改得到每个左端点对应的 max 与 min,在线段树上存储一下每个左端点 (max - max mod d) / d - (min - min mod d) / d + l - 1 的值。
查询时只需要在 [le[i], i] 中线段树二分找最左边的 <= r 的值。
时间复杂度 O(nlogn)。
@accepted code@
#include
@details@
感觉难度系数评到 3100 是不是太高了。。。
毕竟我都会做的题。