题目大意
输入一个整数$n$($1 \leqslant n \leqslant 10^{6}$)求不定方程:$\frac{1}{x} + \frac{1}{y} = \frac{1}{n!}$ 的正整数解$(x,y)$的数目,答案对$10^{9} + 7$取模。
题解
我们处理一下等式。
$$\begin{align*} \frac{1}{x} + \frac{1}{y} &= \frac{1}{n!} \\ \frac{x + y}{xy} &= \frac{1}{n!} \\ \frac{xy}{x + y} &= n! \\ xy &= xn! + yn! \\ xy - xn! - yn! + (n!)^{2} &= (n!)^{2} \\ (x - n!)(y - n!) &= (n!)^2\end{align*}$$
我们设$a = (x - n!)$,$b = (y - n!)$,$c = (n!)^{2}$,则有$ab = c$。
所以$(a,b)$的解数实际就是$(x,y)$的解数。
我们设$(a,b)$的解数为$ans$。
我们设有质数集合$\{ p_{i} | p_{i} \in [1,n]\}$,质数数为$tot$。
我们可以设
$$c = \prod_{i = 1}^{tot} p_{i}^{t_{i}}$$
根据$ab = c$,可以得到
$$\left \{ \begin{align*} a &= \prod_{i = 1}^{tot} p_{i}^{g_{i}} \\ b &= \prod_{i = 1}^{tot} p_{i}^{t_{i} - g_{i}} \end{align*} \right.$$
显然$0 \leqslant g_{i} \leqslant t_{i}$,所以对于每个$g_{i}$的取值数为$t_{i} + 1$,我们可以得到
$$ans = \prod_{i=1}^{tot} ( t_{i} + 1 )$$
所以我们只需要用欧拉筛求出$\{ p_{i} \}$,再暴力求$\{ t_{i} \}$,直接求解即可。
#include <iostream> #define MAX_N (1000000 + 5) using namespace std; const int mod = 1e9 + 7; int n; int p[MAX_N], tot; bool f[MAX_N]; int ans = 1; int main() { cin >> n; for(int i = 2; i <= n; ++i) { if(!f[i]) p[++tot] = i; for(int j = 1; i * p[j] <= n; ++j) { f[i * p[j]] = true; if(!(i % p[j])) break; } } int cnt; for(int i = 1; i <= tot; ++i) { cnt = 0; for(long long j = p[i]; j <= n; j *= p[i]) { cnt = (cnt + (n / j)) % mod; } ans = (long long)ans * (cnt << 1 | 1) % mod; } cout << ans; return 0; }
这里还有一种思路,更像是初中数学题(最后代码是一样的)。
$$\because \frac{1}{x} + \frac{1}{y} = \frac{1}{n!} \\ \therefore \frac{1}{x} < \frac{1}{n! }, \frac{1}{y} < \frac{1}{n!} \\ \therefore x > n! , y > n!$$
我们设$y = n! + k$,则有
$$\begin{align*} \frac{1}{x} + \frac{1}{n! + k} &= \frac{1}{n!} \\ \frac{x + n! + k}{x(n! + k)} &= \frac{1}{n!} \\ \frac{x(n! + k)}{x + n! + k} &= n! \\ x(n! + k) &= xn! + (n!)^{2}+ kn! \\ xk &= (n!)^{2} + kn! \\ x &= \frac{(n!)^{2}}{k} + n! \end{align*}$$
显然$n!$为整数,而$\frac{(n!)^{2}}{k}$也应为整数,所以$k|(n!)^{2}$,我们只需要求出$k$的取值数,也就是$(n!)^{2}$的约数数。剩下的就和上面的代码一样了。