题意
- a n s = ∑ i = 1 n ∑ j = 1 n lcm(i, j) . ( n ≤ 1 0 10 ) ans=\displaystyle\sum_{i = 1}^n\sum_{j = 1}^n\text{lcm(i, j)}.(n\le10^{10}) ans=i=1∑nj=1∑nlcm(i, j).(n≤1010)
这个题目比公约数那个题麻烦多了,首先还是把这个式子拆成公约数的形式:
a
n
s
=
∑
i
=
1
n
∑
j
=
1
n
i
j
(
i
,
j
)
a
n
s
=
∑
d
=
1
n
d
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
n
d
⌋
i
j
[
(
i
,
j
)
=
1
]
a
n
s
=
∑
d
=
1
n
d
(
2
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
i
i
j
[
(
i
,
j
)
=
1
]
−
[
i
=
1
]
)
ans = \sum_{i = 1}^n\sum_{j = 1}^n\frac{ij}{(i,j)} \\ ans = \sum_{d = 1}^nd\sum_{i = 1}^{\lfloor \frac n d \rfloor}\sum_{j = 1}^{\lfloor \frac n d \rfloor}ij[(i,j)=1] \\ ans = \sum_{d = 1}^nd(2\sum_{i = 1}^{\lfloor \frac n d \rfloor}\sum_{j = 1}^i ij[(i,j)=1]-[i=1])
ans=i=1∑nj=1∑n(i,j)ijans=d=1∑ndi=1∑⌊dn⌋j=1∑⌊dn⌋ij[(i,j)=1]ans=d=1∑nd(2i=1∑⌊dn⌋j=1∑iij[(i,j)=1]−[i=1])
设
f
(
n
)
=
∑
i
=
1
n
n
i
[
(
n
,
i
)
=
1
]
f(n)=\displaystyle\sum_{i = 1}^nni[(n,i)=1]
f(n)=i=1∑nni[(n,i)=1],则:
f
(
n
)
=
n
∑
i
=
1
n
i
[
(
n
,
i
)
=
1
]
f
(
n
)
=
n
×
n
ϕ
(
n
)
+
[
n
=
1
]
2
f(n) = n\sum_{i = 1} ^ n i[(n,i)=1]\\ f(n)=n\times\frac{n\phi(n)+[n=1]} 2
f(n)=ni=1∑ni[(n,i)=1]f(n)=n×2nϕ(n)+[n=1]
现在我们来证明一下
n
ϕ
(
n
)
2
=
∑
i
=
1
n
i
[
(
n
,
i
)
=
1
]
\frac{n\phi(n)}2=\displaystyle\sum_{i = 1} ^ n i[(n,i)=1]
2nϕ(n)=i=1∑ni[(n,i)=1],这个实际上就是要我们证明
(
i
,
n
)
=
1
(i,n)=1
(i,n)=1时,
(
n
−
i
,
n
)
=
1
(n-i,n)=1
(n−i,n)=1。我们考虑反证法,假设存在
(
i
,
n
)
=
1
(i,n)=1
(i,n)=1且
(
n
−
i
,
n
)
=
k
(
k
>
1
)
(n-i,n)=k(k>1)
(n−i,n)=k(k>1),那么:
(
n
−
i
)
mod k = 0
①
n
mod k = 0
②
(n-i)\text{ mod k = 0}\ ①\\ n\text{ mod k = 0}\ ②
(n−i) mod k = 0 ①n mod k = 0 ②
②式减去①式,可知:
i
mod
k
=
0
i\text { mod }k = 0
i mod k=0即
(
i
,
n
)
=
k
(i,n)=k
(i,n)=k,与假设矛盾,那么
(
i
,
n
)
=
1
(i,n)=1
(i,n)=1时有
(
n
−
i
,
n
)
=
1
(n-i,n)=1
(n−i,n)=1。那么每对互质的数的和都是
n
n
n,特判一下
n
=
1
n=1
n=1的情况就好了,把
f
(
n
)
f(n)
f(n)代回答案式:
a
n
s
=
∑
d
=
1
n
d
(
2
∑
i
=
1
⌊
n
d
⌋
f
(
i
)
−
[
i
=
1
]
)
a
n
s
=
∑
d
=
1
n
d
(
2
∑
i
=
1
⌊
n
d
⌋
(
i
×
i
ϕ
(
i
)
+
[
i
=
1
]
2
−
[
i
=
1
]
)
a
n
s
=
∑
d
=
1
n
d
∑
i
=
1
⌊
n
d
⌋
i
2
ϕ
(
i
)
ans = \sum_{d = 1}^nd(2\sum_{i = 1}^{\lfloor \frac n d \rfloor}f(i)-[i=1])\\ ans = \sum_{d = 1}^nd(2\sum_{i = 1}^{\lfloor \frac n d \rfloor}(i\times\frac{i\phi(i)+[i=1]}2 -[i=1])\\ ans = \sum_{d = 1}^nd\sum_{i = 1}^{\lfloor \frac n d \rfloor}{i^2\phi(i)}
ans=d=1∑nd(2i=1∑⌊dn⌋f(i)−[i=1])ans=d=1∑nd(2i=1∑⌊dn⌋(i×2iϕ(i)+[i=1]−[i=1])ans=d=1∑ndi=1∑⌊dn⌋i2ϕ(i)
因为
d
d
d我们可以整除分块,所以我们现在只要求
g
(
n
)
=
i
2
ϕ
(
i
)
g(n)=i^2\phi(i)
g(n)=i2ϕ(i)的前缀和,我们把这个东西卷上个
i
d
2
(
x
)
id^2(x)
id2(x),那么:
(
i
d
2
∗
g
)
(
n
)
=
∑
d
∣
n
g
(
d
)
(
n
d
)
2
(
i
d
2
∗
g
)
(
n
)
=
∑
d
∣
n
d
2
ϕ
(
d
)
(
n
d
)
2
(
i
d
2
∗
g
)
(
n
)
=
n
2
∑
d
∣
n
ϕ
(
d
)
(
i
d
2
∗
g
)
(
n
)
=
n
3
(id^2*g)(n)=\sum_{d | n}g(d)(\frac n d)^2\\(id^2*g)(n)=\sum_{d | n}d^2\phi(d)(\frac n d)^2 \\ (id^2*g)(n)=n^2\sum_{d|n}\phi(d)\\ (id^2*g)(n)=n^3
(id2∗g)(n)=d∣n∑g(d)(dn)2(id2∗g)(n)=d∣n∑d2ϕ(d)(dn)2(id2∗g)(n)=n2d∣n∑ϕ(d)(id2∗g)(n)=n3
这就变成了杜教筛的形式,复杂度 O ( n 2 3 ) O(n^{\frac 2 3}) O(n32)。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 3;
const int mod = 1e9 + 7;
const int inv2 = 500000004;
const int inv6 = 166666668;
int prime[N], notp[N], cnt;
int phi[N], Sg[N];
unordered_map<ll, int> SG;
void Get_Prime(int n) {
notp[0] = notp[1] = phi[1] = 1;
for (int i = 2; i <= n; ++ i) {
if (!notp[i]) prime[++ cnt] = i, phi[i] = i - 1;
for (int j = 1; j <= cnt && prime[j] * i <= n; ++ j) {
notp[prime[j] * i] = 1;
phi[prime[j] * i] = 1ll * phi[i] * prime[j] % mod;
if (!(i % prime[j])) break;
(phi[prime[j] * i] += mod - phi[i]) %= mod;
}
}
for (int i = 1; i <= n; ++ i) {
Sg[i] = (Sg[i - 1] + 1ll * phi[i] * i % mod * i % mod) % mod;
}
}
int yici(ll x) { return (x % mod + 1) * (x % mod) % mod * inv2 % mod; }
int erci(ll x) { return (x % mod + 1) * (x % mod) % mod * ((x * 2 + 1) % mod) % mod * inv6 % mod; }
int query(ll n) {
if (n <= 1e6) return Sg[n];
if (SG[n]) return SG[n];
int res = 1ll * yici(n) * yici(n) % mod;
for (ll l = 2, r; l <= n; l = r + 1) {
r = n / (n / l);
(res += mod - 1ll * (erci(r) + mod - erci(l - 1)) * query(n / l) % mod) %= mod;
}
return SG[n] = res;
}
int main() {
ll n, ans = 0;
Get_Prime(N - 3);
cin >> n;
for (ll l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
(ans += 1ll * (yici(r) + mod - yici(l - 1)) * query(n / l) % mod) %= mod;
}
cout << ans << endl;
return 0;
}