带输入值的莫反解法

8.16杭二的莫反题没有推出来

\(\sum_{i=1}^n\sum_{j=1}^nlcm(a_i,a_j)\)

解法:同机房奆佬非出题人解法 不过吊打出题人

\[\begin{align} &\sum_{i=1}^n\sum_{j=1}^nlcm(a_i,a_j)\\ &=\sum_{i=1}^n\sum_{j=1}^n\frac{a_i\times a_j}{gcd(a_i,a_j)}\\ &=\sum_{d=1}\sum_{i=1}^n\sum_{j=1}^n\frac{a_i\times a_j}{d}[d=gcd(a_i,a_j)]\\ &=\sum_{d=1}\sum_{d|a_i}\sum_{d|a_j}\frac{a_i\times a_j}{d}[1=gcd(\frac{a_i}{d},\frac{a_j}{d})]\\ &=\sum_{d=1}\sum_{d|a_i}\sum_{d|a_j}\frac{a_i\times a_j}{d}\sum_{k=1}\mu(k)[k|gcd(\frac{a_i}{d},\frac{a_j}{d})]\\ &=\sum_{d=1}\sum_{k=1}\mu(k)\sum_{dk|a_i}\sum_{dk|a_j}\frac{a_i\times a_j}{d}\\ &=\sum_{T=1}\sum_{k|T}\mu(k)\sum_{T|a_i}\sum_{T|a_j}k\frac{a_i\times a_j}{T}\\ &=\sum_{T=1}^{max\{a_i\}}\sum_{k|T}k\times \mu(k)\sum_{T|a_i}\sum_{T|a_j}\frac{a_i\times a_j}{T}\\ \end{align} \]

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dwn(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
typedef long long ll;
const int mod=998244353;
int n,maxn,cnt,prime[100010],ton[1000010];
ll ans=0,F[1000010],G[1000010],inv[1000010];
bool v[1000010];
void init(int n)
{
	F[1]=1;
	rep(i,2,n)
	{
		if(!v[i])
		{
			prime[++cnt]=i;
			F[i]=1-i;
		}
		for(int j=1;j<=cnt&&prime[j]*i<=n;++j)
		{
			v[prime[j]*i]=1;
			if(i%prime[j]==0)
			{
				F[prime[j]*i]=F[i];
				break;
			}
			F[prime[j]*i]=F[i]*(1-prime[j])%mod;
		}
	}
	rep(i,1,n)
	{
		for(int j=i;j<=n;j+=i)
		{
			G[i]=(G[i]+ll(j)*ton[j])%mod;
		}
		G[i]=G[i]*G[i]%mod;
	}
	inv[1]=1;
	rep(i,2,n)
	{
		inv[i]=(mod-mod/i)*inv[mod%i]%mod;
	}
}
int main()
{
	scanf("%d",&n);
	rep(i,1,n)
	{
		int t;
		scanf("%d",&t);
		ton[t]++,maxn=max(maxn,t);
	}
	init(maxn);
	rep(i,1,maxn)
	{
		ans=(ans+G[i]*inv[i]%mod*F[i]%mod)%mod;
	}
	printf("%lld\n",(ans+mod)%mod);
	return 0;
}
posted @ 2019-08-16 15:59  zmy蒟蒻  阅读(203)  评论(1编辑  收藏  举报