做了几天也不会,最后弃疗看了题解。其实做法大概和题解差不多的,就是没想到势能分析后暴力复杂度是对的。。。
对于某一位,任意时刻两个数的值可能有四种状态(000000,010101,101010,111111)。
考虑从低位往高位依次处理进位关系。假设我们当前处理到某一位,依次维护了更低的位对这一位进位的状态(010101,101010,111111)和时间。一个显然的暴力是依次处理所有的操作,并且求出对更高的位的进位以及这一位最后的结果,注意如果我们某一位初始时或经过某次操作后状态是111111,那么可以直接把状态变成000000并且下一位增加一个111111的进位,所以我们分析的时候不考虑111111状态。
可惜这个复杂度显然是假的,因为连续的一段111111进位到下一层也是相同长度的连续一段111111。
仔细思考一下,我们可以给出如下优化后的算法:对于010101或101010操作直接模拟,将连续的111111操作用链表缩起来。对于一段111111操作,如果操作前这一位的状态为000000,那么会对下一位仍然连续做相同长度的111111进位,可以直接计算贡献并得到下一层一个新的111111连续段;如果是010101或101010,我们将链表拆开模拟,会对下一位交替做010101和101010的进位。
如何分析这个算法的复杂度呢?我们考虑每个位处理的过程,对每个010101和101010操作带333的势能,每个111111操作带444的势能,且当前状态每个111的位也带上222的势能。那么考虑遍历过程,如果遇到一个010101或101010操作,不论操作前状态是哪个,操作后总势能必定减小111,代价被支付了。如果遇到一段连续的111111操作,如果不拆开(操作前状态是000000),那么实际代价是O(1)\mathcal O(1)O(1),势能不变,在下一位有相同长度的111111进位,此时若是非平凡情况,那么由于下一个操作必为010101或101010,可以用它减小的势能支付;如果拆开(操作前状态是010101或101010
Atcoder agc025F
最新推荐文章于 2021-03-10 08:23:53 发布