从别人课件上扒下来的(qwq
问题:
已知 (f(1) cdots f(n)), 且 (g = f * mu), 算 (g(1) cdots g(n))。
解法1
按照定义计算, 即直接按照(g(n) = sum_{d|n} f(d) mu(frac{n}d))计算。
代码(伪):
for(int i=1; i<=n; ++i)
for(int j=1; j<=n/i; ++j)
g[i*j] += f[i] * mu[j];
复杂度是 (O(n log n)) 。
解法2
定义数论函数
[q_i(n) =
egin{cases}
1 quad n=1 \
-1 quad n = p_i \
0 quad else
end{cases}
]
其中 (p_i) 是第 (i) 个素数。
可以发现(mu = q_1 * q_2 * q_3 * cdots), 因此(g = f * q_1 * q_2 * q_3 * cdots) 。
要把一个函数卷上 (q_i) , 只需要 (O(frac{n}{p_i})) 的时间, 因此总复杂度就是 (sum_{p leq n} frac{n}p = O(n log log n)) 。
代码(伪)
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) //j由大到小循环的原因类似0/1背包的优化qwq
g[j * prime[i]] -= g[j];