[AGC038C] LCMs

题目描述

  • 给定一个长度为 \(N\) 的数列 \(A_1, A_2, A_3, \ldots, A_N\)
  • 请你求出 \(\sum_{i=1}^{N}\sum_{j=i+1}^{N}\mathrm{lcm}(A_i,A_j)\) 的值模 \(998244353\) 的结果。
  • \(1 \leq N \leq 2 \times 10^5\)\(1 \leq A_i \leq 10^6\)
  • $ 1\ \leq\ N\ \leq\ 200000 $
  • $ 1\ \leq\ A_i\ \leq\ 1000000 $

思路点拨

这种题目还是很好想到莫比乌斯反演的。我们对于序列中的每一个数记录出现的次数 \(cnt_i\) ,这就是指 \(i\)\(A\) 的出现次数。我们先对原来的式子进行转化。

\[\sum_{i=1}^n\sum_{j=i+1}^n \text{lcm} (A_{i},A_{j}) \]

\[\dfrac{1}{2}(\sum_{i=1}^N \sum_{j=1}^N \text{lcm}(i,j)\times cnt_icnt_j -\sum_{i=1}^n A_i) \]

我们暂且讨论 $\sum_{i=1}^N \sum_{j=1}^N \text{lcm}(i,j)\times cnt_icnt_j $ 的部分:

\[\sum_{i=1}^N\sum_{j=1}^N \dfrac{ij}{\gcd(i,j)}cnt_icnt_j \]

\[\sum_{d=1}^N \sum_{i=1}^N\sum_{j=1}^N \dfrac{ij}{d}cnt_icnt_j[\gcd(i,j)=d] \]

\[\sum_{d=1}^N d\sum_{i=1}^{\lfloor \frac{N}{d}\rfloor} \sum_{j=1}^{\lfloor \frac{N}{d}\rfloor}ij\times cnt_{id} cnt_{jd}[\gcd(i,j)=1] \]

\[\sum_{d=1}^N d \sum_{k=1}^{\lfloor \frac{N}{d}\rfloor} \mu(k) (\sum_{k=1}^{\lfloor \frac{N}{kd}\rfloor} k\times cnt_{kd})^2 \]

我们令 \(T=kd\) 那么

\[\sum_{T=1}^N \sum_{d|T} d\mu(\dfrac{T}{d})(\sum_{i=1}^{\lfloor \frac{N}{T} \rfloor} \dfrac{T}{d}cnt_T)^2 \]

\[\sum_{T=1}^N \sum_{d|T} \dfrac{1}{d}\mu(\dfrac{T}{d})(\sum_{i=1}^{\lfloor \frac{N}{T} \rfloor} Tcnt_T)^2 \]

括号内的式子和逆元 \(O(n \log n)\) 预处理就可以了。这样全部的式子都可以在 \(O(n \log n)\) 的时间内计算。

这里给出一份代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-f;
		ch=getchar(); 
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*f;
}
const int mod=998244353;
int qpow(int a,int b){
	int ans=1,base=a;
	while(b){
		if(b&1) ans=ans*base%mod;
		base=base*base%mod;
		b>>=1;
	}
	return ans;
}
const int MAXN=1e6+10,N=1e6;
int n,A[MAXN],cnt[MAXN];
int mu[MAXN],inv[MAXN],f[MAXN];
int temp[MAXN],g[MAXN];
bool vis[MAXN];
void init(){
	inv[0]=1;
	for(int i=1;i<=N;i++){
		mu[i]=1;
		inv[i]=qpow(i,mod-2);
	} 
	for(int i=2;i<=N;i++){
		if(vis[i]) continue;
		mu[i]=-1;
		for(int j=i*2;j<=N;j+=i){
			vis[j]=1;
			mu[j]=-mu[j];
			if(j%(i*i)==0) mu[j]=0;
		}
	}
	for(int d=1;d<=N;d++)
		for(int T=d;T<=N;T+=d)
			f[T]=(f[T]+(mu[T/d]*inv[d]+mod)%mod)%mod;
	for(int T=1;T<=N;T++)
		for(int i=1;i<=N/T;i++)
			g[T]=(g[T]+i*T*cnt[i*T])%mod; 
}
signed main(){
	n=read();
	for(int i=1;i<=n;i++){
		A[i]=read();
		cnt[A[i]]++;
	}	
	init();
	int ans=0;
	for(int d=1;d<=N;d++)
		for(int k=1;k<=(N/d);k++)
			ans=(ans+mu[k]*g[d*k]%mod*g[d*k]%mod*inv[d])%mod;
	for(int i=1;i<=n;i++)
		ans=(ans-A[i]+mod)%mod;
	cout<<ans*inv[2]%mod;
	return 0; 
}
posted @ 2023-06-15 12:48  Diavolo-Kuang  阅读(5)  评论(0编辑  收藏  举报