题目大意
输入一个整数$n$($1 leqslant n leqslant 10^{6}$)求不定方程:$frac{1}{x} + frac{1}{y} = frac{1}{n!}$ 的正整数解$(x,y)$的数目,答案对$10^{9} + 7$取模。
题解
我们处理一下等式。
$$egin{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!)^2end{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 { egin{align*} a &= prod_{i = 1}^{tot} p_{i}^{g_{i}} \ b &= prod_{i = 1}^{tot} p_{i}^{t_{i} - g_{i}} end{align*} ight.$$
显然$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; }
这里还有一种思路,更像是初中数学题(最后代码是一样的)。
$$ecause frac{1}{x} + frac{1}{y} = frac{1}{n!} \ herefore frac{1}{x} < frac{1}{n! }, frac{1}{y} < frac{1}{n!} \ herefore x > n! , y > n!$$
我们设$y = n! + k$,则有
$$egin{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}$的约数数。剩下的就和上面的代码一样了。