这把打得中规中矩,前期一道签到题出得有点慢了;最后一道铜牌题关键思路是对的,但还是做法有问题超时了。
\(D\) 纯签到
\(J\):每一次考虑排好一整个前缀,那么每次操作至少会让前缀长度加 \(2\),只需要选择 当前已拼好前缀的后一个数 和 其后最右侧的比它小的数 做一次操作即可(手玩即可证明),这样最多只需要 \(\lfloor \frac{n}{2} \rfloor\) 次操作。
\(A\):卡了很久的一道题,最后构造出了一组很强的样例,排查出了问题。具体思路见官解。
\(G\):无解情况很好特判,只需要关注有解情况:对于 \(\forall j \in [1, \lfloor\frac{m}{2}\rfloor]\),将第 \(j\) 列与第 \(m - j + 1\) 列分到一组,这两列中 \(1\) 的数量一定不能超过 \(2\),否则无解;如果小于 \(2\),那么这两列无论哪种方案都会满足要求,不需要考虑;那么就只需要看恰好有 \(2\) 个 \(1\) 的情况,显然最终每一列必须恰好有一个 \(1\),那么根据初始时两个 \(1\) 是否在同一列,就可以知道含有这 \(2\) 个 \(1\) 的两行是必须都操作/不操作,还是必须只对某一行操作。于是我们可以用二分图染色解决这个问题:将每一行当作一个点,边权 \(0/1\) 分别代表两个端点是必须都操作/不操作,还是必须只对某一行操作。对于每个连通块,方案数只能是 \(0\) 或 \(2\),取决于这个连通块内所有边是否均满足条件。所有连通块的方案数作乘法原理即为答案。注意特判 \(m\) 为奇数时中间一列的情况。
code
K. Rainbow Subarray
关键要想到将等差数列的偏移量提前处理掉:先将所有的 \(a_{i}\) 减掉 \(i\)(设为 \(a'\))。这样处理后就有一个重要的性质:将 \(a\) 中的一个子数组变成公差为 \(1\) 的等差数列,等价于将 \(a'\) 中的对应子数组变成全部相同的数(相当于操作后再将偏移量加回来)。这样,问题就变成了:现有最大操作次数 \(k\),考虑所有子数组,求在最大操作次数以内可以变成全相同数的子数组的最大长度。
这个也是经典结论了 —— 都变成序列的中位数一定更优(长度为偶数,上中位数和下中位数之间的数都可以)。操作次数等价于求子数组后一半大 \(-\) 前一半大的值。
蒟蒻赛时写了二分+\(FHQ\),复杂度带两个 \(\log\) 不出意外地 \(T\) 了。事实上二分可以写成双指针(因为在某个子数组中添加一个数,操作次数一定单调不减),通过滑动窗口的方式维护上述值,进而可以省掉一个 \(\log\) 通过。看来还是经验不足qwq。
使用 \(FHQ\),当然是因为它强大的功能:既可以查询维护集合的第 \(k\) 大,也可以查询任何一个数在维护集合中的排名。结合这两个功能,就能够实时维护子树组内添加或者删除一个数时,子数组后一半大 \(-\) 前一半大的值。具体实现写得很麻烦,还要根据区间长度的奇偶性分类讨论,细节见代码。
code
M. Almost Convex
待补
code