[POI 2007] ZAP-Queries
[POI 2007] ZAP-Queries
题目描述
密码学家正在尝试破解一种叫 BSA 的密码。
他发现,在破解一条消息的同时,他还需要回答这样一种问题:
给出 $a,b,d$,求满足 $1 \leq x \leq a$,$1 \leq y \leq b$,且 $\gcd(x,y)=d$ 的二元组 $(x,y)$ 的数量。
因为要解决的问题实在太多了,他便过来寻求你的帮助。
输入格式
输入第一行一个整数 $n$,代表要回答的问题个数。
接下来 $n$ 行,每行三个整数 $a,b,d$。
输出格式
对于每组询问,输出一个整数代表答案。
输入输出样例 #1
输入 #1
2
4 5 2
6 4 3
输出 #1
3
2
说明/提示
数据规模与约定
对于全部的测试点,保证 $1 \leq n \leq 5 \times 10^4$,$1 \leq d \leq a,b \leq 5 \times 10^4$。
解题思路
先给出容斥原理的做法,同时引出莫比乌斯函数。
题目是求有多少个 $x \left( 1 \leq x \leq a \right)$ 和 $y \left( 1 \leq y \leq b \right)$ 满足 $\gcd(x,y)=d$,其中 $\gcd(x,y)=d$ 等价于 $\gcd\left(\frac{x}{d}, \frac{y}{d}\right)=1$。令 $x' = \tfrac{x}{d}$,$y' = \tfrac{y}{d}$,因此问题问题转化为求有多少个 $x' \left( 1 \leq x' \leq \left\lfloor\frac{a}{d}\right\rfloor \right)$ 和 $y' \left( 1 \leq y' \leq \left\lfloor\frac{b}{d}\right\rfloor \right)$ 满足 $\gcd(x',y')=1$。为了简化符号,在下文中令 $a \gets \left\lfloor\tfrac{a}{d}\right\rfloor$,$b \gets \left\lfloor\tfrac{a}{d}\right\rfloor$。
为求互质数对 $(x,y)$ 的数量,我们可以用所有数对的数量 $a \cdot b$ 减去满足 $\gcd(x,y) > 1$ 的数对数量,而 $\gcd(x,y) > 1$ 的数对数量可以通过容斥原理求解。先给出容斥原理的公式 $$\left|\bigcup_{i=1}^{n} S_i\right|=\sum\limits_{1\leq i\leq n}{\left|S_i\right|}-\sum\limits_{1\leq i<j\leq n}{\left|S_i \cap S_j\right|} + \cdots + (-1)^{k+1}\sum\limits_{|T \subseteq\{i\in \mathbb{Z}\mid 1\leq i\leq n\}
|=k}{\left|\bigcap_{i\in T}{S_i}\right|} + \cdots + (-1)^{n+1} \left|\bigcap_{i=1}^{n}{S_i}\right|$$
因此定义 $S_i$ 表示 $\gcd(x,y)$ 为 $i$ 的倍数的数对 $(x,y)$ 的集合,则互质的数对数量就是 $a \cdot b - \left|\bigcup_{i=1}^{\min\{a,b\}} S_i\right|$。进一步的,注意到对于合数 $x = p_{1}^{\alpha_1}p_{2}^{\alpha_2}\cdots p_{k}^{\alpha_k}$(质因数分解表示),$S_x$ 是 $S_{p_i}\left(1\leq i\leq k \right)$ 的子集,因此我们只需考虑质数所对应的集合即可。定义 $P$ 为 $[2,\min\{a,b\}]$ 中的质数构成的集合,于是有 $\left|\bigcup_{i=1}^{\min\{a,b\}} S_i\right| = \left|\bigcup_{i \in P} S_i\right|$,其中 $\left|\bigcap_{i\in T \subseteq P}{S_i}\right| = \left\lfloor \frac{a}{\prod_{i\in T}{i}} \right\rfloor \times \left\lfloor \frac{b}{\prod_{i\in T}{i}} \right\rfloor$。对于 $a \cdot b - \left|\bigcup_{i \in P} S_i\right|$ 展开来看就是 $$\begin{align*} a \cdot b \\ &- \left\lfloor \frac{a}{2} \right\rfloor \times \left\lfloor \frac{b}{2} \right\rfloor - \left\lfloor \frac{a}{3} \right\rfloor \times \left\lfloor \frac{b}{3} \right\rfloor - \left\lfloor \frac{a}{5} \right\rfloor \times \left\lfloor \frac{b}{5} \right\rfloor - \cdots \\ &+ \left\lfloor \frac{a}{2 \cdot 3} \right\rfloor \times \left\lfloor \frac{b}{2 \cdot 3} \right\rfloor + \left\lfloor \frac{a}{2 \cdot 5} \right\rfloor \times \left\lfloor \frac{b}{2 \cdot 5} \right\rfloor + \cdots \\ &- \left\lfloor \frac{a}{2 \cdot 3 \cdot 5} \right\rfloor \times \left\lfloor \frac{b}{2 \cdot 3 \cdot 5} \right\rfloor - \cdots \\ &\vdots \end{align*}$$
可以发现,在上式中当 $|T|$ 为奇数时,对应项 $\left|\bigcap_{i\in T \subseteq P}{S_i}\right|$ 的系数是 $-1$;反之当 $|T|$ 为偶数时,对应项的系数是 $+1$。由此定义莫比乌斯函数:对于 $x = p_{1}^{\alpha_1}p_{2}^{\alpha_2}\cdots p_{k}^{\alpha_k}$,有 $$\mu(x) = \begin{cases} 1 &x=1 \\ (-1)^k &\forall \alpha_i =1 \\ 0 &\exists \alpha_i > 1 \end{cases}$$
从而 $a \cdot b - \left|\bigcup_{i \in P} S_i\right|$ 可以简洁地表示为 $\pmb{\sum_{i=1}^{\min\{a,b\}}{\mu(i) \left\lfloor\tfrac{a}{i}\right\rfloor\left\lfloor\tfrac{b}{i}\right\rfloor}}$。计算该结果的时间复杂度为 $O(\min\{a,b\})$,由于有多组测试样例,总的时间复杂度为 $O(T \cdot \min\{a,b\})$,难以通过。
由数论分块可以知道,$\sum_{i=1}^{n}{\left\lfloor\tfrac{n}{i}\right\rfloor}$ 中的 $\left\lfloor\tfrac{n}{i}\right\rfloor$ 实际上只有 $O(\sqrt{n})$ 种不同的取值,因此可以在 $O(\sqrt{n})$ 时间内计算。同理 $\sum_{i=1}^{\min\{a,b\}}{\mu(i) \left\lfloor\tfrac{a}{i}\right\rfloor\left\lfloor\tfrac{b}{i}\right\rfloor}$ 中的 $\left\lfloor\tfrac{a}{i}\right\rfloor\left\lfloor\tfrac{b}{i}\right\rfloor$ 也只有 $O(\sqrt{a} + \sqrt{b})$ 种不同取值,对应 $O(\sqrt{a} + \sqrt{b})$ 个不同区间 $[l_i, r_i]$,其中 $r_i = \min\left\{\left\lfloor a/\left\lfloor a/l_i\right\rfloor\right\rfloor, \left\lfloor b/\left\lfloor b/l_i\right\rfloor\right\rfloor \right\}$。在每个区间内 $\left\lfloor\tfrac{a}{i}\right\rfloor\left\lfloor\tfrac{b}{i}\right\rfloor$ 的值恒定,因此有 $\sum_{j=l_i}^{r_i}{\mu(j) \left\lfloor\tfrac{a}{j}\right\rfloor\left\lfloor\tfrac{b}{j}\right\rfloor} = \left\lfloor\tfrac{a}{l_i}\right\rfloor\left\lfloor\tfrac{b}{l_i}\right\rfloor\sum_{j=l_i}^{r_i}{\mu(j)}$,只需预处理 $\mu(i)$ 的前缀和即可。
AC 代码如下,时间复杂度为 $O(T \cdot (\sqrt{a} + \sqrt{b}))$:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 5e4 + 5;
int prime[N], mu[N], cnt;
bool vis[N];
void init() {
mu[1] = 1;
for (int i = 2; i < N; i++) {
if (!vis[i]) prime[cnt++] = i, mu[i] = -1;
for (int j = 0; prime[j] * i < N; j++) {
vis[prime[j] * i] = true;
if (i % prime[j] == 0) break;
mu[prime[j] * i] = -mu[i];
}
}
for (int i = 1; i < N; i++) {
mu[i] += mu[i - 1];
}
}
void solve() {
int a, b, d;
cin >> a >> b >> d;
a /= d, b /= d;
if (a > b) swap(a, b);
LL ret = 0;
for (int i = 1; i <= a; i++) {
int j = min(a / (a / i), b / (b / i));
ret += LL(mu[j] - mu[i - 1]) * (a / i) * (b / i);
i = j;
}
cout << ret << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
init();
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
再给出莫比乌斯反演的做法。
先给出莫比乌斯反演的定义,设 $F(n)$ 和 $f(n)$ 是两个数论函数(定义在正整数集上,且取值为复数的函数,即 $f:\mathbb{Z}^+ \mapsto \mathbb{C}$),若满足 $F(n) = \sum_{d \mid n}{f(d)}$,则有 $f(n) = \sum_{d \mid n}\mu(d)F(\tfrac{n}{d})$。
在证明之前,先证明关键性质:$\displaylines{\sum_{d \mid n}{\mu(d)} = \begin{cases} 1 &n=1 \\ 0 &n > 1 \end{cases}}$。设 $n = p_{1}^{\alpha_1}p_{2}^{\alpha_2}\cdots p_{k}^{\alpha_k}$,对因子 $d = p_{1}^{\beta_1}p_{2}^{\beta_2}\cdots p_{k}^{\beta_k} \left( 0 \leq \beta_i \leq \alpha_i \right)$,若存在某个 $\beta_i > 1$ 则 $\mu(d) = 0$,故只需关注 $n' = p_{1} \, p_{2}\cdots p_{k}$ 的因子,即
\begin{align*}
\sum_{d \mid n}{\mu(d)} &= \sum_{d \mid n'}{\mu(d)} \\
&= \sum_{i=0}^{k}{C_{k}^{i} \cdot (-1)^{i}} \\
&= \sum_{i=0}^{k}{C_{k}^{i} \cdot (-1)^{i} \cdot 1^{k-i}} \\
&= (1-1)^{k} = 0 \quad (n>1)
\end{align*}
现在证明反演公式 $f(n) = \sum_{d \mid n}\mu(d)F(\tfrac{n}{d})$。代入 $F(\tfrac{n}{d}) = \sum_{i \mid \tfrac{n}{d}}{f(i)}$ 得到 $f(n)=\sum_{d \mid n}\mu(d)\sum_{i \mid \tfrac{n}{d}}{f(i)}$。交换求和顺序,先考虑交换后 $i$ 的取值范围,由于在交换前当 $d=1$ 时,$i$ 的取值为 $n$ 的所有因子,因此交换后 $i$ 的取值范围就是 $n$ 的所有因子。再考虑交换后 $d$ 的范围,由 $i \mid \tfrac{n}{d}$ 可以得到 $i \cdot d \mid n$ 从而得到 $d \mid \tfrac{n}{i}$。因此交换求和顺序后的结果为 $\sum_{i \mid n}f(i)\sum_{d \mid \tfrac{n}{i}}{\mu(d)}$,结合上述的性质,只有当 $i=n$ 时才有 $\sum_{d \mid \tfrac{n}{i}}{\mu(d)} = 1$,因此 $\sum_{i \mid n}f(i)\sum_{d \mid \tfrac{n}{i}}{\mu(d)} = f(n)$。
莫比乌斯反演还有另外一种更常用的形式,若满足 $F(n) = \sum_{n \mid d}{f(d)}$,则有 $f(n) = \sum_{n \mid d}\mu(\tfrac{d}{n})F(d)$,证明与上述方法类似。
我们一般直接定义 $f(d)$ 为要求的答案,然后再通过 $f(d)$ 推导出 $F(n)$ 的定义,而 $F(n)$ 则容易表示出来。在本题中,我们定义 $f(d)$ 表示满足 $\gcd(x,y)=d$ 且 $1 \leq x \leq a$,$1 \leq y \leq b$ 的数对数量,由 $F(n) = \sum_{n \mid d}{f(d)}$ 知道 $F(n)$ 表示为 $\gcd(x,y)$ 是 $n$ 的倍数的数对数量,容易知道 $F(n) = \left\lfloor\tfrac{a}{n}\right\rfloor\left\lfloor\tfrac{b}{n}\right\rfloor$。
由莫比乌斯反演 $f(d) = \sum_{d \mid n}\mu(\tfrac{n}{d})F(n) = \sum_{d \mid n}\mu(\tfrac{n}{d})\left\lfloor\tfrac{a}{n}\right\rfloor\left\lfloor\tfrac{b}{n}\right\rfloor$。由于 $n = i \cdot d \left( i \in \mathbb{Z}^+ \right)$,因此 $f(d) = \sum_{i=1}^{\min\{\left\lfloor a/d \right\rfloor,\left\lfloor b/d \right\rfloor\}}{\mu(i)\left\lfloor\tfrac{a}{i\cdot d}\right\rfloor\left\lfloor\tfrac{b}{i\cdot d}\right\rfloor}$。令 $a \gets \left\lfloor a/d \right\rfloor$,$b = \left\lfloor b/d \right\rfloor$,就有 $\pmb{\sum_{i=1}^{\min\{a,b\}}{\mu(i)\left\lfloor\tfrac{a}{i}\right\rfloor\left\lfloor\tfrac{b}{i}\right\rfloor}}$,与上述推导出的加粗公式完全一致。
AC 代码同上,时间复杂度为 $O(T \cdot (\sqrt{a} + \sqrt{b}))$。
参考资料
莫比乌斯反演 - OI Wiki:https://oi-wiki.org/math/number-theory/mobius/
莫比乌斯反演 - pengym - 博客园:https://www.cnblogs.com/peng-ym/p/8647856.html
AcWing 215. 破译密码(算法提高课):https://www.acwing.com/video/740/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/19005453