hihoCoder #1867 GCD

在集合 \([n]\) 上使用容斥原理。

固定 \(i\),考虑有多少个 \(j \in [n]\) 满足 \(\gcd(i, j) = \gcd(a_i, a_j) = 1\),将此数目记作 \(f_i\)。暂时不考虑条件 $ i \le j $ 。

考虑 \([n]\) 的某些子集。\(S_{x,y} := \\{ i\in [n] \colon x\mid i, y \mid a_i \\}\)

\(a_6 = 4\) 为例,\(6\) 的素因子有 \(2, 3\)\(4\) 的素因子有 \(2\)

考虑集合 \(S_{1, 2}, S_{2, 1}, S_{2, 2}, S_{3, 1}, S_{3, 2}\),对这些集合用容斥原理(即求出 \([n]\) 中【不属于这些集合中的任一集合】的元素有多少个)即可求得 \(f_i\)

在对 \(S_1, S_2, \dots, S_n\) 用容斥原理时,若 \(S_i \subset S_j\)\(i\ne j\))则可将 \(S_i\) 去掉。

注意到 \(S_{3,2}, S_{2, 2}\) 都是 \(S_{1, 2}\) 的子集,所以有些子集是不用考虑的。实际上我们考虑
\(S_{1, 2}, S_{2, 1}, S_{3, 1}\) 即可。

\(i\) 的素因子个数记作 \(c_i\)。求解 \(f_i\) 需要计算 \(2^{c_i + c_{a_i} }\) 个集合的基数。

机械地采用容斥原理其实做了很多重复计算。

容斥原理涉及求一些集合的交集的基数,这些交集可表为 \(S_{x, y}\) 其中 \(x, y\) 都是若干个素数的乘积。

\(A, B\) 为一些质数的集合,\(p_A, p_B\) 分别为其中元素的乘积(\(p_{\emptyset} = 1\))。以下也将 \(S_{p_A,p_B}\) 写作 \(S_{A,B}\)

在使用容斥原理时我们实际上是要求 \(|S_{A,B}|\),注意到 \(|S_{A,B}|\) 每次出现,其系数都是 \(-1^{|A|+|B|}\),故我们考虑 \(|S_{A,B}|\) 出现了多少次。易见,\(|S_{A,B}|\) 出现在 \(f_i\) 的表达式中当且 \(p_A\mid i\)\(p_B \mid a_i\),故 \(|S_{A,B}|\) 出现了 \(|S_{A,B}|\) 次。因此有
\begin{equation}
\sum_i f_i = \sum_{A,B} (-1)^{|A|+|B|} |S_{A,B}|^2
\end{equation}

\begin{equation}
|S_{A,B}| =\sum_i [p_A|i,\,p_B|a_i] = \sum_{k} [p_B \mid a_{kp_A}]
\end{equation}
于是
\begin{equation}
\sum_i f_i = \sum_{A,B} (-1)^{|A|+|B|} \left( \sum_{k} [p_B \mid a_{kp_A}] \right)^2 \label{E:3}
\end{equation}
借助 Möbius 函数,\eqref{E:3} 可写成
\begin{equation}
\sum_i f_i = \sum_{x}\mu(x) \sum_y \mu(y) \left( \sum_{k} [y \mid a_{kx}] \right)^2
\end{equation}

计算方法:枚举 \(x\),枚举 \(k\),枚举 \(y\)\(y\)\(kx\) 的因子),为每个 \(\mu(y)\ne 0\)\(y\) 维护一个计数器,并将这些 \(y\) 放入一个列表。

posted @ 2018-11-14 13:30  Pat  阅读(280)  评论(0编辑  收藏  举报