问题:求 (sum_{i=1}^n f(i)),其中 (f(i)) 是积性函数,满足 (f(p^k) (p in prime)) 可以快速求,(1 leq n leq 10^{10})
Part 1
设 (operatorname{g}(a,b)=sum_{i=1}^a [iin prime operatorname{or} pmin_i>prime_b] f(i)),其中 (pmin_i) 表示 (i) 的最小质因数,而 (prime_b) 则表示第 (b) 小的质数。
显然 (operatorname{g}(a,infty)) 就是质数部分的积性函数之和。
考虑这个东西怎么推。
(g(a,b)=egin{cases} g(a,b-1) (a<prime_b^2) \ g(a,b-1)-f(prime_b)(g(leftlfloorfrac{a}{prime_b} ight floor,b-1)-g(prime_{b-1},b-1)) (otherwise) end{cases})
发现 (g(a,b)) 可以由 (g(a,b-1)) 推导过来,只需要 (g(a,b-1)) 剔掉 (sum_{i=1}^a [i ot in prime operatorname{and} pmin_i=prime_b ] f(i)) 的部分即可。
上面那个式子就描述了这一过程。因为 (f(i)) 是积性函数,所以如果剔掉以 (prime_b) 因数的数字的话会给答案减去一个 (f(prime_b)) 的贡献。
这个看上去比较简单。下一个。
Part 2
既然质数部分我们会做了,那么考虑合数部分要怎么做...
根据上述 (g) 函数的构造方法,我们也可以构造一个 (S) 函数。
构造一个 (S) 函数使 (S(a,b)=sum_{i=2}^a [pmin_i geq prime_b] f(i))
很显然我们要求的东西就是 (S(n,0))
(S(a,b)=egin{cases} S(a,b+1) (a < prime_b^2)\ g(a,infty)-sum_{i=1}^{b-1}f(prime_i)+sum_{prime_k^i leq a,k > b} f(prime_k^i)(S(leftlfloorfrac{a}{prime_k^i} ight floor,k)+[i>1]) end{cases})
左边那个式子是算质数,即 (f(prime_b)) 的贡献,而右边那个式子是算合数的贡献。顺便一提由于 (i=1) 的时候有点难搞所以直接跳过去了,所以如果右边没有 ([i>1]) 的话,(f(prime_b^i)) 将会被略过,如果右边把 ([i>1]) 改成 ([i]) 的话那么又会多算质数的贡献,所以就是 ([i>1])
发现上面那两坨东西如果暴力去算的话肯定就是大于 (mathcal{O}(n ln n)) 的,相当暴力,但是我们发现对于每个 (a) ,我们需要计算的关键部分的形式是类似于 (leftlfloor frac{n}{i} ight floor) 的,于是可以直接数论分块,复杂度降为 (mathcal{O}(frac{n^{frac{3}{4}}}{log n})) ,可以通过。
代码...懒得写,直接贺(