AT5200 [AGC038C] LCMs

título Descripción

Dada una longitud \ (N \) es el número de columnas \ (A_1, A_2, A_3, \ ldots, a_n \) .
Por favor obtiene \ (\ sum_ {i = 1 } ^ {N} \ sum_ {j = i + 1} ^ {N} \ mathrm {lcm} (A_i, A_j) \) valores mueren \ (998244353 \) resultados.
\ (. 1 \ Leq N \ Leq 2 \ ^ 10 5,1 veces \ Leq A_i \ Leq. 6 10 ^ \) .

solución del problema

\ (\ Sum_ {i = 1} ^ {N} \ sum_ {j = i + 1} ^ {N} \ mathrm {lcm} (A_i, A_j) \)

\ (= \ Frac {\ sum_ {i = 1} ^ {N} \ sum_ {j = 1} ^ {N} \ mathrm {lcm} (A_i, A_j) - \ sum_ {i = 1} ^ {N} a_i} {2} \)

En tanto que mantenemos \ (\ sum_ {i = 1 } ^ {N} \ sum_ {j = 1} ^ {N} \ mathrm {} lcm (A_i, A_j) \) es fácil respuesta.

\ (\ Sum_ {i = 1} ^ {N} \ sum_ {j = 1} ^ {N} \ mathrm {lcm} (A_i, A_j) \)

\ (= \ Sum_ {d = 1} ^ {Max} \ frac {1} {d} \ sum_ {i = 1} ^ {N} A_i \ sum_ {j = 1} ^ {N} A_j [\ mathrm { gcd} (A_i, A_j) == d] \)

\ (F (d) = \ sum_ {i = 1} ^ {N} A_i \ sum_ {j = 1} ^ {N} A_j [d | \ mathrm {gcd} (A_i, A_j)], f (d ) = \ sum_ {i = 1} ^ {N} A_i \ sum_ {j = 1} ^ {N} A_j [\ mathrm {gcd} (A_i, A_j) == d] \)

El \ (F (d) = \ sum f (e) [d | e] \)

Acerca \ (M \) , podemos calcular todos los múltiplos de cada número y las plazas y dejar que ellos (todas las combinaciones de dos legal)

Mobius disponible por la inversión, \ (F (D) = \ F. SUM (E) * \ MU (\ frac {E} {D}) \)

Todo lo anterior puede ser enumeración múltiple \ (O (n * ln_n) \) estrellas, acoplado al inverso de procesamiento lineal.

#include <iostream>
#include <cstdio>
#define ll long long
#define int long long
using namespace std;
const int N = 2e5 + 5, M = 1e6 + 5;
int n, a[N], mx, v[M], prime[M], tot, mu[M];
ll ans, t[M], inv[M], f[M], sum, F[M];
const int mod = 998244353;
inline int read()
{
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
void init(int n)
{
	mu[1] = 1;
	for(int i = 2; i <= n; i ++)
	{
		if(!v[i]) {prime[++ tot] = i; mu[i] = -1;}
		for(int j = 1; j <= tot && prime[j] * i <= n; j ++)
		{
			v[i * prime[j]] = 1;
			if(i % prime[j] == 0)
			{
				mu[i * prime[j]] = 0;
				break;
			}
			mu[i * prime[j]] = - mu[i];
		}
	}
	inv[0] = inv[1] = 1;
	for(int i = 2; i <= n; i ++) inv[i] = (mod - mod / i) * inv[mod % i] % mod;
}
void work()
{
	n = read();
	for(int i = 1; i <= n; i ++) a[i] = read(), t[a[i]] ++, mx = max(mx, a[i]), sum = (sum + a[i]) % mod;
	init(mx);
	for(int i = 1; i <= mx; i ++)
	{
		for(int j = i; j <= mx; j += i) F[i] = (F[i] + t[j] * j) % mod;
		F[i] = (F[i] * F[i]) % mod;
	}
	for(int i = 1; i <= mx; i ++) for(int j = i; j <= mx; j += i) f[i] = (f[i] + (F[j] * mu[j / i] % mod + mod)) % mod;
	for(int d = 1; d <= mx; d ++) ans = (ans + inv[d] * f[d] % mod) % mod;
	ans = (ans - sum + mod) % mod * inv[2] % mod;
	printf("%lld\n", (ans + mod) % mod);
}
signed main() {return work(), 0;}

Supongo que te gusta

Origin www.cnblogs.com/Sunny-r/p/12566673.html
Recomendado
Clasificación