[AGC038C] LCMs 题解
ShiRoZeTsu · · 题解
一道比较简单的莫反练习题。
题意
给定长度为
题解
首先,考虑把问题转化一下。设
所以考虑如何求出
所以可以莫反:
枚举
设
设
CODE:
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;
const int maxk = 1e6;
const ll mod = 998244353;
int n, m, tot;
int prime[maxn>>1], mu[maxn];
ll c[maxn], f[maxn], g[maxn];
bool not_prime[maxn];
ll fpm(ll a, ll k) {
ll res = 1;
while(k) {
if(k&1) res = res*a % mod;
a = a*a % mod;
k >>= 1;
}
return res;
}
const ll inv2 = fpm(2, mod-2);
void prework() {
mu[1] = 1;
for(int i = 2; i <= n; i++) {
if(!not_prime[i]) prime[++tot] = i, mu[i] = -1;
for(int j = 1; j <= tot && i*prime[j] <= n; j++) {
not_prime[i*prime[j]] = true;
if(i%prime[j] == 0) {
mu[i*prime[j]] = 0;
break;
}
mu[i*prime[j]] = -mu[i];
}
}
for(int i = 1; i <= n; i++)
for(int j = 1; i*j <= n; j++)
f[i*j] = (f[i*j] + (1ll * mu[j] * i * j % mod * j % mod + mod) % mod) % mod;
for(int i = 1; i <= n; i++)
f[i] = (f[i] + f[i-1]) % mod;
for(int T = 1; T <= n; T++)
for(int i = 1; i <= n/T; i++)
g[T] = (g[T] + 1ll * i * c[i*T] % mod) % mod;
}
int main() {
scanf("%d", &m);
ll res = 0;
for(int i = 1, x; i <= m; i++) {
scanf("%d", &x);
c[x]++;
res = (res - x%mod + mod) % mod;
n = max(n, x);
}
prework();
for(int i = 1; i <= n; i++) {
ll x = (f[i] - f[i-1] + mod) % mod;
res = (res + x * g[i] % mod * g[i] % mod) % mod;
}
printf("%lld\n", res * inv2 % mod);
return 0;
}