NKOJP2468 Sum of LCM/luoguP3911 最小公倍数之和

题目:传送门

Problem

Solution

对于这种求多个后面跟个gcd,lcm的式子一般都要用莫比乌斯反演。

想办法将式子化出[n==1]形式

过程推导如下:

i=1nj=1nlcm(Ai,Aj)(以下n因为与Ai同阶,所以沿用)

=i=1nj=1nlcm(i,j)×cnti×cntj

=i=1nj=1ni×jgcd(i,j)×cnti×cntj=k=1ni=1nj=1n[gcd(i,j)==k]i×jk×cnti×cntj

=k=1ni=1nkj=1nk[gcd(i,j)==1]ik×jkk×cntik×cntjk

=k=1ni=1nkj=1nkd|gcd(i,j)μ(d)×ik×jkk×cntik×cntjk

=k=1nd=1nki=1nkdj=1nkdμ(d)×ikd×jkdk×cntikd×cntjkd

=k=1ndk=1nki=1ndkj=1ndkμ(d)×ikd×jkdk×cntikd×cntjkd

T=dk,则

=k=1nT=1nki=1nTj=1nTμ(Tk)×iT×jTk×cntiT×cntjT

=k=1nT=1nki=1nTj=1nTμ(Tk)×i×j×T×Tk×cntiT×cntjT

=T=1nTd|Tμ(d)×d(i=1nTcntiT×i)2

预处理出f[T]=d|Tμ(d)×d,最后暴力计算剩余部分即可。

时间复杂度O(nn)

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX_N = 50000 + 5;
int n,a[MAX_N],cnt[MAX_N];
int prime[MAX_N],isprime[MAX_N],tot,mu[MAX_N];
ll f[MAX_N],ans;
int main(){
	mu[1]=1;
	for(int i=2;i<=50000;i++){
		if(!isprime[i]){
			prime[++tot]=i;
			mu[i]=-1;
		}
		for(int j=1;j<=tot && i*prime[j]<=50000;j++){
			isprime[i*prime[j]]=1;
			if(i%prime[j]==0) break;
			mu[i*prime[j]]=-mu[i];
		}
	}
	for(int i=1;i<=50000;i++)
		for(int j=i;j<=50000;j+=i)
			f[j]+=1ll*i*mu[i];
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		cnt[a[i]]++;
	}
	for(int i=1;i<=50000;i++){
		ll tmp=0;
		for(int j=1;j<=50000/i;j++) tmp+=1ll*cnt[i*j]*j;
		ans+=1ll*i*f[i]*tmp*tmp;
	}
	printf("%lld\n",ans);
	return 0;
}
posted @   Thermalrays  阅读(99)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示