洛谷P3911 最小公倍数之和 莫比乌斯反演经典转换

题目链接

题解:

刚拿到这道题目,发现是 n n n个离散的数,很难处理。因此,我们需要对问题进行转化:

∑ i = 1 N ∑ j = 1 N l c m ( i , j ) ∗ c n t [ i ] ∗ c n t [ j ] \sum_{i=1}^N\sum_{j=1}^Nlcm(i,j)*cnt[i]*cnt[j] i=1Nj=1Nlcm(i,j)cnt[i]cnt[j]

c n t cnt cnt表示该数出现的次数。

下面可以对上面的式子进行化简:

∑ i = 1 N ∑ j = 1 N l c m ( i , j ) ∗ c n t [ i ] ∗ c n t [ j ] \sum_{i=1}^N\sum_{j=1}^Nlcm(i,j)*cnt[i]*cnt[j] i=1Nj=1Nlcm(i,j)cnt[i]cnt[j]

= ∑ i = 1 N ∑ j = 1 N i ∗ j g c d ( i , j ) ∗ c n t [ i ] ∗ c n t [ j ] =\sum_{i=1}^N\sum_{j=1}^N\frac {i*j}{gcd(i,j)}*cnt[i]*cnt[j] =i=1Nj=1Ngcd(i,j)ijcnt[i]cnt[j]

= ∑ k = 1 N ∑ i = 1 N ∑ j = 1 N [ g c d ( i , j ) = = k ] i ∗ j k ∗ c n t [ i ] ∗ c n t [ j ] =\sum_{k=1}^N\sum_{i=1}^N\sum_{j=1}^N[gcd(i,j)==k]\frac {i*j}{k}*cnt[i]*cnt[j] =k=1Ni=1Nj=1N[gcd(i,j)==k]kijcnt[i]cnt[j]

= ∑ k = 1 N ∑ i = 1 N k ∑ j = 1 N k [ g c d ( i , j ) = = 1 ] i ∗ j ∗ k ∗ c n t [ i k ] ∗ c n t [ j k ] =\sum_{k=1}^N\sum_{i=1}^{\frac Nk}\sum_{j=1}^{\frac Nk}[gcd(i,j)==1]i*j*k*cnt[ik]*cnt[jk] =k=1Ni=1kNj=1kN[gcd(i,j)==1]ijkcnt[ik]cnt[jk]

= ∑ k = 1 N ∑ i = 1 N k ∑ j = 1 N k ∑ d ∣ g c d ( i , j ) μ ( d ) ∗ i ∗ j ∗ k ∗ c n t [ i k ] ∗ c n t [ j k ] =\sum_{k=1}^N\sum_{i=1}^{\frac Nk}\sum_{j=1}^{\frac Nk}\sum_{d|gcd(i,j)}\mu(d)*i*j*k*cnt[ik]*cnt[jk] =k=1Ni=1kNj=1kNdgcd(i,j)μ(d)ijkcnt[ik]cnt[jk]

= ∑ k = 1 N ∑ d = 1 N k ∑ i = 1 N k d ∑ j = 1 N k d d 2 ∗ μ ( d ) ∗ i ∗ j ∗ k ∗ c n t [ i k d ] ∗ c n t [ j k d ] =\sum_{k=1}^N\sum_{d=1}^{\frac Nk}\sum_{i=1}^{\frac N{kd}}\sum_{j=1}^{\frac N{kd}}d^2*\mu(d)*i*j*k*cnt[ikd]*cnt[jkd] =k=1Nd=1kNi=1kdNj=1kdNd2μ(d)ijkcnt[ikd]cnt[jkd]

= ∑ k = 1 N ∑ k d = 1 N d 2 ∗ μ ( d ) ∑ i = 1 N k d ∑ j = 1 N k d i ∗ j ∗ k ∗ c n t [ i k d ] ∗ c n t [ j k d ] =\sum_{k=1}^N\sum_{kd=1}^{N}d^2*\mu(d)\sum_{i=1}^{\frac N{kd}}\sum_{j=1}^{\frac N{kd}}i*j*k*cnt[ikd]*cnt[jkd] =k=1Nkd=1Nd2μ(d)i=1kdNj=1kdNijkcnt[ikd]cnt[jkd]

= ∑ T = 1 N T ( ∑ d ∣ T d ∗ μ ( d ) ) ∑ i = 1 N T ∑ j = 1 N T i ∗ j ∗ c n t [ i T ] ∗ c n t [ j T ] =\sum_{T=1}^NT(\sum_{d|T}d*\mu(d))\sum_{i=1}^{\frac N{T}}\sum_{j=1}^{\frac N{T}}i*j*cnt[iT]*cnt[jT] =T=1NT(dTdμ(d))i=1TNj=1TNijcnt[iT]cnt[jT] 注意这步经典转换

= ∑ T = 1 N T ( ∑ d ∣ T d ∗ μ ( d ) ) ( ∑ i = 1 N T c n t [ i ∗ T ] ∗ i ) 2 =\sum_{T=1}^NT(\sum_{d|T}d*\mu(d))(\sum_{i=1}^{\frac NT}cnt[i*T]*i)^2 =T=1NT(dTdμ(d))(i=1TNcnt[iT]i)2

发现这个式子现在不能进一步进行优化,因此,只能转化到这个式子。

下面计算这个式子。

我们可以对第一个括号内的式子进行预处理,第二个括号内的式子可以暴力求解。整个程序的时间复杂度就是 O ( n l o g n ) O(nlogn) O(nlogn)。这题数据量为 n ≤ 50000 n\leq50000 n50000,可以通过。

实现细节见代码:

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int MAXN = 1e6 + 10;
const int mod = 1e9 + 7;
int primes[MAXN], cnt, mu[MAXN], f[MAXN], cnt1[MAXN];
bool vis[MAXN];
void init(int n) {
	mu[1] = 1;
	for (int i = 2; i <= n; i++) {
		if (!vis[i]) {
			primes[cnt++] = i;
			mu[i] = -1;
		}
		for (int j = 0; primes[j] <= n / i; j++) {
			vis[i * primes[j]] = true;
			if (i % primes[j] == 0) {
				mu[i * primes[j]] = 0;
				break;
			}
			mu[i * primes[j]] = -mu[i];
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int j = i; j <= n; j += i) {
			f[j] += mu[i] * i;
		}
	}
}
signed main() 
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int n;
	init(50005);
	cin >> n;
	for (int i = 0; i < n; i++) {
		int x;
		cin >> x;
		cnt1[x]++;
	}
	int ans = 0;
	for (int i = 1; i <= 50000; i++) {
		int now = 0;
		for (int j = 1; j <= 50000 / i; j++) {
			now += cnt1[j * i] * j;
		}
		ans += i * f[i] * now * now;
	}
	cout << ans << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值