Description
给你一个\(1\ldots n\)的排列\(b_i\)和一个长为\(n\)的序列\(a_i\),\(a_i\)初始全为\(0\)。然后要求支持以下两种操作:
add l r
:将\(a_i\)中区间\([l, r]\)的每一个位置都加一。query l r
:查询\(\sum_{i = l}^r\lfloor\frac{a_i}{b_i}\rfloor\)。
多组数据(一个点最多五组)。\(1\leq n\leq 10^5\)。
Solution
设\(c_i = \lfloor\frac{a_i}{b_i}\rfloor\)。首先一次加操作可能会导致一些\(c_i\)的变动,也可能不造成。那么假设我们在每次变动的时候都进行单点修改,那么对于位置\(i\)其被修改次数最多为\(\lfloor\frac{q}{b_i}\rfloor\),因此即使在极限情况下修改次数也不过是\(O(n\log n)\)级别的,用树状数组维护\(c_i\)即可。
接下来考虑怎样才能知道\(c_i\)是否在这次操作后需要改动。不妨记\(d_i\)表示\(i\)这个位置还要加多少才能迎来下一次\(c_i\)变动,那么我们每次add
就是对一个区间的\(d_i\)减,如果\(d_i = 0\)的话就需要修改。注意到此时\(d_i\)一定是该区间内最小的,因此不断取最小值变动相应\(c_i\),然后再修改\(d_i\)即可。
Code
1 |
|