ProjectEuler 432 - Totient sum

好久没做题了,前一段时间旅游了一小会儿然后趁着 **USC 的机会溜回家开始了长达七天的暑假生活。

闲着无聊做了一下 PE-432 ……

Problem

令

S(n,m)=∑_i=1mϕ(n×i)S(n, m) = \sum\_{i=1}^{m} \phi(n \times i)

求 S(510510,1011)S(510510, 10^{11})

Solution

令 n=pqn = pq ,且 pp 为质数,有

S(n,m)=(p−1)S(q,m)+S(n,⌊mp⌋)S(n, m) = (p - 1) S(q, m) + S(n, \lfloor \frac{m}{p} \rfloor)

于是我们只要计算

S(1,m)=∑_i=1mϕ(i)S(1, m) = \sum\_{i = 1}^m \phi(i)

即可。

线性筛法可以去死了。我们可以采用 @dyh 的理性愉悦 O(n23)O(n^{\frac{2}{3}}) 的方法:

令 SfS_f 表示函数 ff 的前缀和函数,即

Sf(n)=∑i=1nf(i),S_f(n) = \sum_{i = 1}^n f(i),

我们要求 Sϕ(n)S_{\phi} (n) 。

令 gn=∑d∣nfng_n = \sum_{d|n} f_n 于是有

S∗g(n)=∑∗i=1n∑∗d∣if(d)=∑∗i=1nSf(⌊ni⌋)S*g(n) = \sum*{i = 1}^n \sum*{d|i} f(d) = \sum*{i=1}^n S_f(\lfloor \frac{n}{i} \rfloor)

这个等式只要注意到每个 f(i)f(i) 被加的次数都是 ⌊ni⌋\lfloor\frac{n}{i}\rfloor 就好了。

如果我们能够快速计算 Sg(n)S_g(n) ,就可以利用

S∗f(n)=Sg(n)−∑∗i=2nSf(⌊ni⌋)S*f(n) = S_g(n) - \sum*{i = 2}^n S_f(\lfloor \frac{n}{i} \rfloor)

来计算 Sf(n)S_f(n) 了。

当 f(n)=ϕ(n)f(n) = \phi(n) 时, g(n)=∑d∣nfn=ng(n) = \sum_{d|n} f_n = n ,Sg(n)=12n(n+1)S_g(n) = \frac{1}{2} n(n+1) 。我们用筛法算出 i≤n23i \leq n^{\frac{2}{3}} 时的 Sf(i)S_f(i) ,其余的暴力记忆化递归做下去,复杂度是 O(n23)O(n^{\frac{2}{3}}) 。

我一开始把 mm 看成了 101410^{14} 跑了 20min 才跑出来, m=1011m = 10^{11} 时只要 3s 就可以了……