BZOJ2721或洛谷1445 [Violet]樱花
BZOJ原题链接
洛谷原题链接
其实推导很简单,只不过我太菜了想不到。。。又双叒叕去看题解
简单写下推导过程。
原方程:$$\dfrac{1}{x} + \dfrac{1}{y} = \dfrac{1}{n!}$$
通分:$$\dfrac{x + y}{xy} = \dfrac{1}{n!}$$
十字相乘:$$(x + y) \times n! = xy$$
把\((x + y) \times n!\)移到右项:$$xy - (x + y) \times n! = 0$$
两边同时加上\((n!)^2\):$$(n!)^2 - (x + y) \times n! + xy = (n!) ^ 2$$
左项因式分解:$$(x - n!) \times (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;
}
posted on 2018-11-01 16:52 Iowa_Battleship 阅读(152) 评论(0) 编辑 收藏 举报