P3911 最小公倍数之和
Description
-
给定整数 n n n 和 n n n 个整数 a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,…,an,求
∑ i = 1 n ∑ j = 1 n lcm ( a i , a j ) \sum_{i = 1}^n \sum_{j = 1}^n \operatorname{lcm}(a_i, a_j) i=1∑nj=1∑nlcm(ai,aj) -
对于 100 % 100\% 100% 的数据, 1 ≤ n , a i ≤ 5 × 1 0 4 1 \le n, a_i \le 5\times 10^4 1≤n,ai≤5×104。
Solution
直接反演不行,考虑计算贡献。
设 max { a 1 , a 2 , … , a n } = m \max\{a_1, a_2, \dots, a_n\} = m max{a1,a2,…,an}=m。
观察到值域(即
m
m
m)
≤
5
×
1
0
4
\le 5\times 10^4
≤5×104,开一个数组
c
i
c_i
ci 记录数
i
i
i 的出现次数。
∑
i
=
1
n
∑
j
=
1
n
lcm
(
a
i
,
a
j
)
=
∑
i
=
1
m
∑
j
=
1
m
lcm
(
i
,
j
)
c
i
c
j
=
∑
i
=
1
m
∑
j
=
1
m
i
j
gcd
(
i
,
j
)
c
i
c
j
=
∑
i
=
1
m
∑
j
=
1
m
∑
d
=
1
m
i
j
d
[
gcd
(
i
,
j
)
=
d
]
c
i
c
j
=
∑
d
=
1
m
∑
i
=
1
⌊
m
d
⌋
∑
j
=
1
⌊
m
d
⌋
(
i
d
)
(
j
d
)
d
[
gcd
(
i
,
j
)
=
1
]
c
i
d
c
j
d
=
∑
d
=
1
m
∑
i
=
1
⌊
m
d
⌋
∑
j
=
1
⌊
m
d
⌋
i
j
d
c
i
d
c
j
d
∑
k
∣
gcd
(
i
,
j
)
μ
(
k
)
=
∑
d
=
1
m
d
∑
k
=
1
⌊
m
d
⌋
μ
(
k
)
∑
i
=
1
⌊
m
d
⌋
[
k
∣
i
]
i
c
i
d
∑
j
=
1
⌊
m
d
⌋
[
k
∣
j
]
j
c
j
d
=
∑
d
=
1
m
d
∑
k
=
1
⌊
m
d
⌋
μ
(
k
)
(
∑
i
=
1
⌊
m
d
k
⌋
i
k
c
i
d
k
)
2
=
∑
d
=
1
m
d
∑
k
=
1
⌊
m
d
⌋
μ
(
k
)
k
2
(
∑
i
=
1
⌊
m
T
⌋
i
c
i
T
)
2
=
∑
T
=
1
m
(
∑
i
=
1
⌊
m
T
⌋
i
c
i
T
)
2
∑
k
∣
T
μ
(
k
)
k
2
(
T
k
)
=
∑
T
=
1
m
T
(
∑
i
=
1
⌊
m
T
⌋
i
c
i
T
)
2
∑
k
∣
T
μ
(
k
)
k
=
∑
T
=
1
m
T
(
∑
i
=
1
⌊
m
T
⌋
i
c
i
T
)
2
∑
k
∣
T
μ
(
k
)
k
\begin{aligned} \sum_{i = 1}^n \sum_{j = 1}^n \operatorname{lcm}(a_i, a_j) & = \sum_{i = 1}^m \sum_{j = 1}^m \operatorname{lcm}(i, j) c_i c_j \\ & = \sum_{i = 1}^m \sum_{j = 1}^m \dfrac{ij}{\gcd(i, j)} c_i c_j \\ & = \sum_{i = 1}^m \sum_{j = 1}^m \sum_{d = 1}^m \dfrac{ij}{d} [\gcd(i, j) = d] c_i c_j \\ & = \sum_{d = 1}^m \sum_{i = 1}^{\left\lfloor\frac{m}{d}\right\rfloor} \sum_{j = 1}^{\left\lfloor\frac{m}{d}\right\rfloor} \dfrac{(id)(jd)}{d} [\gcd(i, j) = 1] c_{id} c_{jd} \\ & = \sum_{d = 1}^m \sum_{i = 1}^{\left\lfloor\frac{m}{d}\right\rfloor} \sum_{j = 1}^{\left\lfloor\frac{m}{d}\right\rfloor} ijd\, c_{id}\, c_{jd} \sum_{k\mid \gcd(i, j)} \mu(k) \\ & = \sum_{d = 1}^m d \sum_{k = 1}^{\left\lfloor\frac{m}{d}\right\rfloor} \mu(k) \sum_{i = 1}^{\left\lfloor\frac{m}{d}\right\rfloor} [k\mid i]\, i\, c_{id} \sum_{j = 1}^{\left\lfloor\frac{m}{d}\right\rfloor} [k\mid j]\, j\, c_{jd} \\ & = \sum_{d = 1}^m d \sum_{k = 1}^{\left\lfloor\frac{m}{d}\right\rfloor} \mu(k) \left(\sum_{i = 1}^{\left\lfloor\frac{m}{dk}\right\rfloor} ik\, c_{idk}\right)^2 \\ & = \sum_{d = 1}^m d \sum_{k = 1}^{\left\lfloor\frac{m}{d}\right\rfloor} \mu(k) k^2 \left(\sum_{i = 1}^{\left\lfloor\frac{m}{T}\right\rfloor} i\, c_{iT} \right)^2 \\ & = \sum_{T = 1}^m \left(\sum_{i = 1}^{\left\lfloor\frac{m}{T}\right\rfloor} i\, c_{iT} \right)^2 \sum_{k\mid T} \mu(k) k^2 \left(\dfrac{T}{k} \right) \\ & = \sum_{T = 1}^m T \left(\sum_{i = 1}^{\left\lfloor\frac{m}{T}\right\rfloor} i\, c_{iT} \right)^2 \sum_{k\mid T} \mu(k) k \\ & = \sum_{T = 1}^m T \left(\sum_{i = 1}^{\left\lfloor\frac{m}{T}\right\rfloor} i\, c_{iT} \right)^2 \sum_{k\mid T} \mu(k) k \end{aligned}
i=1∑nj=1∑nlcm(ai,aj)=i=1∑mj=1∑mlcm(i,j)cicj=i=1∑mj=1∑mgcd(i,j)ijcicj=i=1∑mj=1∑md=1∑mdij[gcd(i,j)=d]cicj=d=1∑mi=1∑⌊dm⌋j=1∑⌊dm⌋d(id)(jd)[gcd(i,j)=1]cidcjd=d=1∑mi=1∑⌊dm⌋j=1∑⌊dm⌋ijdcidcjdk∣gcd(i,j)∑μ(k)=d=1∑mdk=1∑⌊dm⌋μ(k)i=1∑⌊dm⌋[k∣i]icidj=1∑⌊dm⌋[k∣j]jcjd=d=1∑mdk=1∑⌊dm⌋μ(k)⎝⎜⎛i=1∑⌊dkm⌋ikcidk⎠⎟⎞2=d=1∑mdk=1∑⌊dm⌋μ(k)k2⎝⎜⎛i=1∑⌊Tm⌋iciT⎠⎟⎞2=T=1∑m⎝⎜⎛i=1∑⌊Tm⌋iciT⎠⎟⎞2k∣T∑μ(k)k2(kT)=T=1∑mT⎝⎜⎛i=1∑⌊Tm⌋iciT⎠⎟⎞2k∣T∑μ(k)k=T=1∑mT⎝⎜⎛i=1∑⌊Tm⌋iciT⎠⎟⎞2k∣T∑μ(k)k
首先
μ
\mu
μ 的线性筛是
O
(
m
)
\Omicron(m)
O(m) 的。
对于 ∑ k ∣ T μ ( k ) k \sum_{k\mid T} \mu(k) k ∑k∣Tμ(k)k,用经典套路枚举倍数 Θ ( m 1 + m 2 + m 3 + ⋯ ) = Θ ( m ln m ) \Theta\left(\dfrac{m}{1} + \dfrac{m}{2} + \dfrac{m}{3} + \cdots \right) = \Theta(m\ln m) Θ(1m+2m+3m+⋯)=Θ(mlnm) 预处理。
∑ T = 1 m T ( ∑ i = 1 ⌊ m T ⌋ i c i T ) 2 \sum_{T = 1}^m T \left(\sum_{i = 1}^{\left\lfloor\frac{m}{T}\right\rfloor} i\, c_{iT} \right)^2 ∑T=1mT(∑i=1⌊Tm⌋iciT)2 直接暴力也是 Θ ( m ln m ) \Theta(m\ln m) Θ(mlnm) 的。
总时间复杂度为
Θ
(
m
ln
m
)
\Theta(m\ln m)
Θ(mlnm)。还带大常数
Code
// 18 = 9 + 9 = 18.
#include <iostream>
#include <cstdio>
#define Debug(x) cout << #x << "=" << x << endl
#define int long long
using namespace std;
const int MAXN = 5e4 + 5;
const int N = 5e4;
int p[MAXN], mu[MAXN], res[MAXN];
bool vis[MAXN];
void pre()
{
mu[1] = 1;
for (int i = 2; i <= N; i++)
{
if (!vis[i])
{
p[++p[0]] = i;
mu[i] = -1;
}
for (int j = 1; j <= p[0] && i * p[j] <= N; j++)
{
vis[i * p[j]] = true;
if (i % p[j] == 0)
{
mu[i * p[j]] = 0;
break;
}
mu[i * p[j]] = mu[i] * mu[p[j]];
}
}
for (int i = 1; i <= N; i++)
{
for (int j = 1; i * j <= N; j++)
{
res[i * j] += mu[i] * i;
}
}
}
int a[MAXN], c[MAXN];
signed main()
{
pre();
int n, m = 0;
scanf("%lld", &n);
for (int i = 1; i <= n; i++)
{
scanf("%lld", a + i);
m = max(m, a[i]);
c[a[i]]++;
}
int ans = 0;
for (int i = 1; i <= m; i++)
{
int tmp = 0;
for (int j = 1; j <= m / i; j++)
{
tmp += j * c[j * i];
}
ans += i * tmp * tmp * res[i];
}
printf("%lld\n", ans);
return 0;
}