莫比乌斯反演的计算

从别人课件上扒下来的(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) = \begin{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];
posted @ 2020-04-23 15:01  xwmwr  阅读(160)  评论(0编辑  收藏  举报