Escolhido no material didático de outras pessoas (qwq
O problema:
Conhecendo \ (f (1) \ cdots f (n) \) e \ (g = f * \ mu \) , calcule \ (g (1) \ cdots g (n) \) .
Solução 1
Calcule de acordo com a definição, ou seja, diretamente de acordo com \ (g (n) = \ sum_ {d | n} f (d) \ mu (\ frac {n} d) \) .
Código ( pseudo ):
for(int i=1; i<=n; ++i)
for(int j=1; j<=n/i; ++j)
g[i*j] += f[i] * mu[j];
A complexidade é \ (O (n \ log n) \) .
Solução 2
Definir funções teóricas dos números
Onde \ (p_i \) é o número primo \ (i \) .
Você pode encontrar \ (\ mu = q_1 * q_2 * q_3 * \ cdots \) , então \ (g = f * q_1 * q_2 * q_3 * \ cdots \) .
Para rolar uma função para \ (q_i \) , leva apenas \ (O (\ frac {n} {p_i}) \) , portanto a complexidade total é \ (\ sum_ {p \ leq n} \ frac { n} p = O (n \ log \ log n) \) .
Código ( pseudo )
for(int i=1; i<=n; ++i) g[i] = f[i];
for(int i=1; i<=pr_cnt; ++i)
for(int j = n/prime[i]; j>0; --j) //这样算的原因类似0/1背包qwq
g[j * prime[i]] -= g[j];