The meaning of problems
求 $\sum_{i=a}^b \sum_{j=1}^i \frac{lcm(i,j)}{i}$.
analysis
Just requires a prefix and,
$$\begin{aligned}
\sum_{i=1}^n \sum_{j=1}^i \frac{lcm(i,j)}{i} &= \sum_{i=1}^n \sum_{j=1}^i \frac{j}{gcd(i,j)} \\
&= \sum_{d=1}^n \sum _{i=1}^n \sum_{j=1}^i \frac{j}{d} \cdot [gcd(i,j)=1] \\
&= \sum_{d=1}^n \sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor} \sum_{j=1}^i j \cdot [gcd(i,j)=1]
\end{aligned}$$
Its rear part raised, i.e. seek $ \ sum_ {i = 1} ^ ni \ cdot [gcd (i, n) = 1] $, for which a fixed value has a gcd summation routine, i.e. reverse twenty-two pair:
If $ n = 1 $, and is 1;
若 $n>1$,因为 $gcd(i, n) = gcd(n-i, n)$ 且 $\displaystyle \sum_{i=1}^n i\cdot [gcd(i,n)=1] = \sum_{i=1}^{n-1} i\cdot [gcd(i,n)=1]$,
$ \ Displaystyle \ sum_ {i = 1} ^ {n-1} i \ cdot [gcd (i, n) = 1] + \ sum_ {i = n-1} ^ 1i \ cdot [gcd (i, n) = 1] = n \ varphi (n) $, and so for the $ n \ varphi (n) / 2 $.
Integrated obtained $ \ displaystyle \ sum_ {i = 1} ^ ni \ cdot [gcd (i, n) = 1] = \ frac {n \ varphi (n) + [n = 1]} {2} $.
The specific implementation, $ [i = 1] $ established only $ n-$, except 2 can be raised, i.e., the original formula = $ \ displaystyle \ frac {1} {2} (\ sum_ {d = 1} ^ n \ sum_ {i = 1} ^ {\ left \ lfloor \ frac {n} {d} \ right \ rfloor} i \ varphi (i) + n) $.
The only problem is how to get request $ \ displaystyle S (n) = \ sum_ {i = 1} ^ ni \ varphi (i) $.
According to Du teach sieve,
设 $\displaystyle S(n) = \sum_{i=1}^n f(i)$,$f(n) = n\varphi (n), \ g(n) = n$.
$\displaystyle f*g = \sum_{d|n} d \varphi (d) \cdot \frac{n}{d} = n\sum_{d|n}\varphi (d) = n^2$.
因此 $\displaystyle S(n) = \sum_{i=1}^n i^2 - \sum_{d=2}^n d\cdot S(\left \lfloor \frac{n}{d} \right \rfloor)$.
On the outermost layer and then the number of sets to block.
Code
#include <algorithm> #include <cstdio> #include <cstring> #include <map> #include<unordered_map> using namespace std; const int maxn = 2000010; typedef long long ll; const ll mod = 1000000007; const ll inv2 = (mod+1)>>1; const ll inv6 = 166666668; //166666668 ll T, a, b, pri[maxn], tot, phi[maxn], sum_phi_d[maxn]; bool vis[maxn]; unordered_map MOD;<LL, LL> mp_phi_d; // can be replaced unordered_map, about three times faster LL S_phi_d (LL X) { IF (X <MAXN) return sum_phi_d [X]; IF (mp_phi_d [X]) return mp_phi_d [X]; LL RET = X * (X + . 1 )% MOD * ( 2 * X% MOD + . 1 )% MOD * INV6% MOD; // % knock into *, wasting one hour for (LL I = 2 , J; I <= X ; I = J + . 1 ) { J = X / (X / I); RET = (RET - S_phi_d (X / I) * (I + J)% MOD * (J-I + . 1 )% MOD * INV2% MOD MOD +)% } return mp_phi_d[x] = ret; } void initPhi_d() { phi[1] = 1; for (int i = 2; i < maxn; i++) { if (!vis[i]) pri[++tot] = i, phi[i] = i-1; for (int j = 1; j <= tot && i * pri[j] < maxn; j++) { vis[i * pri[j]] = true; if (i % pri[j] == 0) { phi[i * pri[j]] = phi[i] * pri[j] % mod; break; } else { phi[i * pri[j]] = phi[i] * phi[pri[j]] % mod; } } } for (int i = 1; i < maxn; i++) sum_phi_d[i] = (sum_phi_d[i - 1] + phi[i]*i) % mod; } //ll G(ll n) //{ // //printf("G:%lld\n", n); // return (S_phi_d(n)+1) % mod; //} ll solve(ll n) { ll res = 0; for(ll i = 1, j;i <= n;i = j+1) { j = n / (n / i); res = (res + S_phi_d(n/i) * (j-i+1) % mod) % mod; } return (res+n)*inv2%mod; } int main() { initPhi_d(); scanf("%lld%lld", &a, &b); printf("%lld\n", (solve(b)-solve(a-1)+mod) % mod); return 0; }
Reference links:
1. https://blog.csdn.net/FromATP/article/details/74999989
2. https://www.cnblogs.com/owenyu/p/7397687.html