莫比乌斯反演的计算

从别人课件上扒下来的(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];
原文地址:https://www.cnblogs.com/tztqwq/p/12760647.html