Chain Reaction

好题,介绍一下向上取整的整除分块

首先来看一下另一种做法吧

先看这篇文章

解释一下,再次需要操作的次数实际上就是还有多少个连续的\(1\)的段,不难发现在攻击力为\(k\)的时候,像广搜一样操作\(x\)次后,与操作一次攻击力为\(xk\)的操作是等价的,所以有最后的答案是\(ans_0+ans_k+ans_{2k}+...\)

然后来解释一下我的做法,首先这道题目跟Chip and Ribbon这道题目非常像,都可以转化成积木大赛

那么这道题目怎么转化呢?首先对一个确定的\(k\),将每个\(a_i\)除以\(k\)并且向上取整,然后做出差分数组就好了,不难证明这是正确的

问题是怎么优化,实际上,我们使用转化对象法,不从\(k\)的角度考虑,而从每个数字的角度考虑,不难想到整除分块

但是这里是向上取整,我们不能简单的将蓝书上的推导,所有下取整符号换成上取整符号,小于等于号和大于等于号都取反来做,尽管这样的推导是正确的,但是最后分的段没有分完全。比如如果我们这么做了,那么每一段就是\([g(x),x]\),然而有可能\(g(x)-1\)处的值也与\(x\)的值相同

所以这样就会导致TLE,但是仍然有一个正确的结论:最多只能分成\(O(2\sqrt{k})\)段,因为仍然只有可能有这么多种取值

那么也就是说,我们仍然可以使用这样的算法:最开始令\(L=1\),然后每次循环找到一个最大的\(R\),使得\(\lceil \frac{n}{L}\rceil=\lceil \frac{n}{R}\rceil\),之后再令\(L=R\)即可,如果能找到这样的\(R\)的话,我们的循环也是最多进行\(O(2\sqrt{k})\)次的

那么这个\(R\)怎么找呢?实际上,通过讨论\(n\)是否整除\(d\),我们可以得到如下恒等式:\(\lceil \frac{n}{d}\rceil=\lfloor \frac{n+d-1}{d}\rfloor\),于是我们就可以将向上取整转化为向下取整,即每一次循环的时候,找最大的\(R\)使得\(\lfloor \frac{n+L-1}{L}\rfloor=\lfloor \frac{n+R-1}{R}\rfloor\),也就是\(\lfloor \frac{n-1}{L}\rfloor=\lfloor \frac{n-1}{R}\rfloor\),这就是我们熟悉的整除分块的形式了

那么现在时间复杂度正确了,怎么统计答案呢?实际上,我们发现答案只与差分数组有关,所以我们循环讨论每一个怪物,如果这个怪物的血量比前一个的高,那么这里的差分肯定为正数(反之为负数,处理方法一样,下面只讨论正数的情况),我们对这个怪物进行上面的循环,然后将答案数组(e.g.,\(ans_k\)表示攻击力为\(k\)的时候的答案)的对应位置加上对应贡献,然后对上一个怪物进行同样的循环,然后将答案数组的对应位置减去对应贡献,最后在总的统计就好了

posted @ 2024-04-28 22:31  最爱丁珰  阅读(2)  评论(0编辑  收藏  举报