【莫比乌斯反演】[AGC038C] LCMs

门(洛谷的门不知道什么时候修好)

题目

∑ i = 1 n ∑ j = i + 1 n l c m ( a i , a j ) \sum_{i=1}^n\sum_{j=i+1}^nlcm(a_i,a_j) i=1nj=i+1nlcm(ai,aj)

题解

∑ i = 1 n ∑ j = i + 1 n l c m ( a i , a j ) ∑ i = 1 n ∑ j = 1 n l c m ( a i , a j ) − ∑ i = 1 n a i 2 \sum_{i=1}^n\sum_{j=i+1}^nlcm(a_i,a_j)\\ \frac {\sum_{i=1}^n\sum_{j=1}^nlcm(a_i,a_j)-\sum_{i=1}^na_i}2 i=1nj=i+1nlcm(ai,aj)2i=1nj=1nlcm(ai,aj)i=1nai
我们推比较复杂的
∑ i = 1 n ∑ j = 1 n l c m ( a i , a j ) ∑ i = 1 n ∑ j = 1 n a i a j g c d ( a i , a j ) ∑ d = 1 M 1 d ∑ d ∣ a i ∑ d ∣ a j a i a j [ g c d ( a i , a j ) = = d ] ∑ d = 1 M 1 d ∑ d ∣ a i ∑ d ∣ a j a i a j ∑ e ∣ g c d ( a i , a j ) d μ ( e ) ∑ d = 1 M ∑ e = 1 ⌊ M d ⌋ μ ( e ) d ( ∑ e d ∣ a i a i ) 2 \sum_{i=1}^n\sum_{j=1}^nlcm(a_i,a_j)\\ \sum_{i=1}^n\sum_{j=1}^n\frac{a_ia_j}{gcd(a_i,a_j)}\\ \sum_{d=1}^M\frac1d\sum_{d|a_i}\sum_{d|a_j}a_ia_j[gcd(a_i,a_j)==d]\\ \sum_{d=1}^M\frac1d\sum_{d|a_i}\sum_{d|a_j}a_ia_j\sum_{e|\frac{gcd(a_i,a_j)}d}\mu(e)\\ \sum_{d=1}^M\sum_{e=1}^{\lfloor\frac M d\rfloor}\frac{\mu(e)}d(\sum_{ed|a_i}a_i)^2\\ i=1nj=1nlcm(ai,aj)i=1nj=1ngcd(ai,aj)aiajd=1Md1daidajaiaj[gcd(ai,aj)==d]d=1Md1daidajaiajedgcd(ai,aj)μ(e)d=1Me=1dMdμ(e)(edaiai)2
f ( x ) = ∑ x ∣ a i a i f(x)=\sum_{x|a_i}a_i f(x)=xaiai
∑ T = 1 M f 2 ( T ) ∑ d ∣ T μ ( T d ) d \sum_{T=1}^Mf^2(T)\sum_{d|T}\frac{\mu(\frac Td)}{d} T=1Mf2(T)dTdμ(dT)
f 2 ( x ) = ∑ d ∣ x μ ( x d ) d f2(x)=\sum_{d|x}\frac{\mu(\frac xd)}{d} f2(x)=dxdμ(dx)
∑ T = 1 M f 2 ( T ) f 2 ( T ) \sum_{T=1}^Mf^2(T)f2(T) T=1Mf2(T)f2(T)
f , f 2 f,f2 f,f2都可以用埃筛 O ( n l o g n ) O(nlogn) O(nlogn)求出来
f f f时,我们需要维护一个桶方便我们累加

f ( x ) = ∑ x ∣ i t i f(x)=\sum_{x|i}t_i f(x)=xiti
因为 M A X a i MAXa_i MAXai较小,于是就做完啦

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+10,M=1e6;
const ll mod=998244353;
ll quick_mul(ll a,ll k)
{
	ll ans=1;
	while(k)
	{
		if(k&1)ans=ans*a%mod;
		a=a*a%mod;
		k>>=1;
	}return ans;
}
ll inv(ll a){return quick_mul(a,mod-2);}
int n;
int a[N],t[N];
ll f1[N],f2[N];
int miu[N];
int z[N],p;
bool vis[N];
void Sieve()
{
	miu[1]=1;
	for(int i=2;i<=M;i++)
	{
		if(!vis[i])z[++p]=i,miu[i]=-1;
		for(int j=1;j<=p&&i*z[j]<=M;j++)
		{
			vis[i*z[j]]=1;
			if(i%z[j]==0)break;
			miu[i*z[j]]=-miu[i];
		}
	}
	for(int i=1;i<=M;i++)
	{
		ll invd=inv(1ll*i);
		for(int j=i;j<=M;j+=i)
		{
			f1[i]=(f1[i]+t[j])%mod;
			f2[j]=(f2[j]+miu[j/i]*invd%mod+mod)%mod;
		}		
	}
}
int main()
{
	int maxx=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		t[a[i]]=(t[a[i]]+a[i])%mod;
		maxx=max(maxx,a[i]);
	}
	Sieve();
	ll ans=0;
	for(int i=1;i<=maxx;i++)
	ans=(ans+f1[i]*f1[i]%mod*f2[i]%mod)%mod;
	ans=((ans-f1[1])%mod+mod)%mod;
	printf("%lld",ans*inv(2ll)%mod);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值