BZOJ原题链接
洛谷原题链接
其实推导很简单,只不过我太菜了想不到。。。又双叒叕去看题解
简单写下推导过程。
原方程:$$dfrac{1}{x} + dfrac{1}{y} = dfrac{1}{n!}$$
通分:$$dfrac{x + y}{xy} = dfrac{1}{n!}$$
十字相乘:$$(x + y) imes n! = xy$$
把((x + y) imes n!)移到右项:$$xy - (x + y) imes n! = 0$$
两边同时加上((n!)^2):$$(n!)^2 - (x + y) imes n! + xy = (n!) ^ 2$$
左项因式分解:$$(x - n!) imes (y - n!) = (n!) ^ 2$$
设(a = x - n!, b = y - n!),则方程变为:$$ab = (n!) ^ 2$$
显然确定(a)就能确定(b),也能确定(x, y),所以(a)有几组解即是原方程(x, y)解的组数。
而根据算术基本定理,(n! = prod limits _{i = 1} ^ k p_i ^ {c_i}),所以((n!) ^ 2 = prod limits _{i = 1} ^ k p_i ^ {2c_i})。
再根据约数个数定理,((n!) ^ 2)的约数个数即是(prod limits _{i = 1} ^ k (2c_i + 1)),这就是答案
#include<cstdio>
using namespace std;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
int pr[N];
bool v[N];
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
int main()
{
int i, s = 1, c, n, l = 0;
long long j;
n = re();
v[0] = v[1] = 1;
for (i = 1; i <= n; i++)
{
if (!v[i])
pr[++l] = i;
for (j = 1; j <= l; j++)
{
if (i * pr[j] > n)
break;
v[i * pr[j]] = 1;
if (!(i % pr[j]))
break;
}
}
for (i = 1; i <= l; i++)
{
c = 0;
for (j = pr[i]; j <= n; j *= pr[i])
c = (1LL * c + n / j) % mod;
s = 1LL * s * (c << 1 | 1) % mod;
}
printf("%d", s);
return 0;
}