https://codeforces.com/problemset/problem/1553/F
大意
求
pk=1≤i,j≤k∑aimodaj,
其中
$2 \le n \le 2 \cdot 10^5 , 1 \le a_i \le 3 \cdot 10^5 , a_i \neq a_j if i \ne j$
方法
考虑 p 的差分数组 Pi:=pi−pi−1 则有:
Pm=max(i,j)=m∑aimodaj
考虑从前到后枚举 ai ,保证当前枚举的下标是所有枚举过的中最大的。
定义 dv={0,1} 表示是否有值为 v 的数出现过,那么对于当前的下标 i ,
j=1∑i−1aimodaj=j=1∑max(ak)(aimodj)dj=j=1∑max(ak)(ai−j⌊jai⌋)dj=aij=1∑max(ak)dj−j=1∑max(ak)⌊jai⌋(jdj)
考虑用树状数组维护 dj 和 jdj 的前缀和,对 ⌊jai⌋ 进行整除分块,复杂度 O(nmaxaklogmaxak) 。
接下来考虑
j=1∑i−1ajmodai=j=1∑max(ak)(jmodai)dj=j=1∑max(ak)(j−ai⌊aij⌋)dj
此时 ⌊aij⌋ 块的长度固定为 ai
复杂度 O(∑iai1maxaklogmaxak)=O(maxaklognlogmaxak)
常数优化
开启O2下本地最大数据用时在1.5秒左右,不开启O2,在6.5秒左右。
考虑对于小区间直接循环求和而不使用树状数组,可以节省求和的开销。
优化后开启O2下本地最大数据用时在1.0秒左右,不开启O2,在2.5秒左右。
代码