整除分块 + 树状数组.
先考虑给定一个伤害值 $d$ ,如何计算施放了多少次亵渎.
将每个随从生命值 $x$ 换成需要被攻击的次数,即 $\lfloor \frac{x-1}{d}\rfloor +1$ ,就可以把 $d$ 看作 $1$ ,即每次造成 $1$ 点伤害.
那么施放的次数就是最大的 $x$ ,使得 $1,2,3,\dots, x$ 作为生命值在随从中都出现过,再加上 $1$ .
考虑对于每个 $d$ 都直接维护出答案,询问时利用树状数组查询 $[L,R]$ 内的区间和.
每加入一个数 $x$ 的时候,对它整除分块,它对一段区间 $[L,R]$ 的贡献都是加入了一个数 $k$ .
对每个 $k$ 用 set 维护它在哪些位置是作为最大的 $x$ ,将 $[L,R]$ 内 $k-1$ 作为最大的 $x$ 的位置全部更新一遍.答案.
由于只有增加数字的操作,所以对于每个位置 $d$ ,更新次数不会超过 $\frac {n}{d}$ .
时间复杂度 $O(n\log^2n+n\sqrt n)$ .
1 | //%std |