[每日 C] Light Switches
前言
虽然说看过题解的 \(\rm{C}\) 没有自己做的必要
但是我没看懂啊
开了一个之前的时间胶囊, 其中 \(50 \%\) 的部分都没有实现, 汗
不过至少可以在学校控制自己
然后就是物理隔断很有用, 不知道怎么物理隔断 \(\rm{B}\) 站
思路
首先考虑一盏灯被点亮的区间, 不难发现形如
\([a_i + \lambda k, (\lambda + 1) k)\) , 其中 \(\lambda\) 为正偶数
问题转化为
$ \forall i \in [1, n] , [a_i + \lambda k, (\lambda + 1) k) $ , 是否存在一个点 \(p\) , 使得所有区间包含 \(p\)
不难发现对于所有 \(i\) , 区间形如一些长度相同的段, 但是怎么处理
首先考虑什么情况之下无解
不难发现当 \(\displaystyle \exists i, j \textrm{ s.t. } \frac{|a_i - a_j|}{k} \textrm{ mod } 2 = 1\) 时无解
但是如果你朴素做法, 判无解都超时
一如既往的润去看了 \(\rm{TJ}\) , 今天睡这么久怎么还是困
模拟几组样例, 不难发现只有 \(\max a_i\) 往后的部分才是有用的
根据 \(2k\) 次一个周期, 我们可以 \(a_i \gets a_i \textrm{ mod } 2k\) , 这样就把 \(a_i\) 放缩到了一个小范围且不影响答案
仅仅这样还不够, 你稍微分析可以发现答案一定在 \(\max a_i \sim \max a_i + k\) 之间 \((\)注意右边是开的\()\)
具体一点, 你发现出了这个区间后面的都是循环的, 不考虑
所以现在, 问题转化为, 求 \([a_{\max}, a_{\max} + k)\) 区间中, 第一个被 \(n\) 个区间覆盖的点
不难发现可以用差分处理, 假设当前的答案为 \(p\) , 那么我们只需要找到原串中第一个 \(a_{\max} + ans \textrm{ mod } 2k = p\) 的点即可
总结一下, 首先注意到可以放缩
放缩完之后, 用差分快速处理覆盖, 随后 \(\mathcal{O} (k)\) 做出变换后的答案
简单对应到原序列即可
更一般的, 你注意到事实上所有 \(a_{\max} + ans \textrm{ mod } 2k = p\) 的 \(ans\) 都是符合要求的, 这是因为循环性, 而循环区间最大是 \(4k\) , 简单操作即可
进行一个复习
题意
给定一组 , 表示第 个元素对应的区间为
求最小的 使得
- 定义合法情况, 要求输出一组合法情况 / 合法情况的最值问题 / 求方案数
- 列出合法情况需要满足的表达式, 在原序列中贪心选择最优情况
- 构造: 先推性质, 不行打表
- 找到不合法情况在什么时候出现, 通过对不合法情况的转化构造最优的合法情况
- 先找到一组合法解, 然后在基础上进行调整
- 找到所有情况统一的构造方案
- 循环 / 同余类问题一般可以找到类似循环节的东西
不难发现如果存在, 一定会在 \(\Big[\max a_i, \max a_i + k\Big]\) 中取得一个最优解
想到枚举区间中的点, 转化成判定性问题
但是至少要 \(\mathcal{O} (1)\) 判断不然我不炸了吗
考虑点 \(x\) 合法对应的性质
考虑快速维护 \(\displaystyle \left\lceil\frac{x - a_i}{k}\right\rceil\) , 不难发现在 \(\Big[\max a_i, \max a_i + k\Big]\) 中, \(\forall i, \Delta \leq 1\)
如果能够维护每个 \(i\) 对应的分割点, 即可简单约束答案
之前的做法多半是神经
总结
循环类问题一定要将考虑范围缩小, 一般使用取余等方法
注意最后答案一定要映射回原串


浙公网安备 33010602011771号