思路
这个题目一开始我也不会做,是看了题解区 @yingzhaoyang 大佬的题解之后才明白怎么做的。
首先看这个不定方程:
$$
\frac{1}{x}+\frac{1}{y}=\frac{1}{n!}
$$
我们可以将等号左边的式子通分加起来,得到:
$$
\frac{x+y}{xy}=\frac{1}{n!}=\frac{1}{\frac{xy}{x+y}}
$$
这个时候:
$$
\frac{xy}{x+y}=n!
$$
我们这里把 $n!,y$ 看成常数就行了,这样就可以得到:
$$
x=\frac{n!y}{y-n!}
$$
为了将这个分母变得简单,我们此时令:
$$
y=n!+k
$$
这样就可以得到最终的$x$的方程:
$$
x=\frac{(n!)^2}{k}+n!
$$
看到了吗,这就是@yingzhaoyang 大佬这样设$y$的原因。
所以这个问题可以等价于:找出 $(n!)^2$ 的约数的个数。
找一个阶乘的约数个数可以回顾 阶乘分解。只不过这里是求$(n!)^2$ 的约数的个数,记得对每个质数的次数翻一倍即可。
然后就是简单的组合数学问题,一个约数可以转化为各种不同的质数以及各质数不同的个数。答案即为:
$$
\prod_{i=1}^{n}{(c_i+1)}
$$
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10, Mod = 1e9 + 7;
int primes[N], cnt;
bool vis[N];
typedef long long ll;
void init(int n){
for (int i = 2; i <= n; i ++ ){
if (!vis[i]) primes[cnt ++ ] = i;
for (int j = 0; j < cnt and primes[j] <= n / i; j ++ ){
vis[primes[j] * i] = 1;
if (i % primes[j] == 0) break;
}
}
}
int get(int x, int p){
int res = 0;
while (x){
res = (res + x / p) % Mod;
x /= p;
}
return res;
}
int main(){
int n;
cin >> n;
init(n);
int ans = 1;
for (int i = 0; i < cnt; i ++ )
ans = (ll) ans * (2 * get(n, primes[i]) + 1) % Mod;
cout << ans;
return 0;
}