【题解】Luogu-P3911 最小公倍数之和

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=1nj=1nlcm(ai,aj)

  • 对于 100 % 100\% 100% 的数据, 1 ≤ n , a i ≤ 5 × 1 0 4 1 \le n, a_i \le 5\times 10^4 1n,ai5×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=1nj=1nlcm(ai,aj)=i=1mj=1mlcm(i,j)cicj=i=1mj=1mgcd(i,j)ijcicj=i=1mj=1md=1mdij[gcd(i,j)=d]cicj=d=1mi=1dmj=1dmd(id)(jd)[gcd(i,j)=1]cidcjd=d=1mi=1dmj=1dmijdcidcjdkgcd(i,j)μ(k)=d=1mdk=1dmμ(k)i=1dm[ki]icidj=1dm[kj]jcjd=d=1mdk=1dmμ(k)i=1dkmikcidk2=d=1mdk=1dmμ(k)k2i=1TmiciT2=T=1mi=1TmiciT2kTμ(k)k2(kT)=T=1mTi=1TmiciT2kTμ(k)k=T=1mTi=1TmiciT2kTμ(k)k
首先 μ \mu μ 的线性筛是 O ( m ) \Omicron(m) O(m) 的。

对于 ∑ k ∣ T μ ( k ) k \sum_{k\mid T} \mu(k) k kTμ(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=1TmiciT)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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值