不定方程
题目链接:ybt高效进阶6-2-3
题目大意
给你 n,问你 1/x+1/y=1/n! 这个不定方程有多少个正整数解。
思路
看到这个就开始化式子:
1
/
x
+
1
/
y
=
1
/
n
!
1/x+1/y=1/n!
1/x+1/y=1/n!
x
n
!
+
y
n
!
=
x
y
xn!+yn!=xy
xn!+yn!=xy
y
(
x
−
n
!
)
=
x
n
!
y(x-n!)=xn!
y(x−n!)=xn!
y
=
x
n
!
/
(
x
−
n
!
)
y=xn!/(x-n!)
y=xn!/(x−n!)
然后发现分母不太好搞的样子,直接用值代替。
t
=
x
−
n
!
t=x-n!
t=x−n!
x
=
n
!
+
t
x=n!+t
x=n!+t
y
=
(
n
!
+
t
)
n
!
/
t
y=(n!+t)n!/t
y=(n!+t)n!/t
y
=
(
n
!
)
2
/
t
+
n
!
y=(n!)^2/t+n!
y=(n!)2/t+n!
然后你分析一下就会发现,你就是要
t
t
t 是
(
n
!
)
2
(n!)^2
(n!)2 的因子。
那就把
n
!
n!
n! 质因数分解,答案就是
∏
(
2
×
c
i
+
1
)
\prod(2\times c_i+1)
∏(2×ci+1)。(要乘二是因为平方这个质数的个数翻倍了)
代码
#include<cstdio>
#define ll long long
#define mo 1000000007
using namespace std;
int n, prime[1000001];
ll ans;
bool np[1000001];
void get_prime(int n) {
for (int i = 2; i <= n; i++) {
if (!np[i]) prime[++prime[0]] = i;
for (int j = 1; j <= prime[0] && 1ll * i * prime[j] <= n; j++) {
np[i * prime[j]] = 1;
if (i % prime[j] == 0) break;
}
}
}
int main() {
scanf("%d", &n);
get_prime(n);
ans = 1;
for (int i = 1; i <= prime[0]; i++) {
ll num = 0;
for (ll j = prime[i]; j <= n; j *= prime[i]) {
num = (num + n / j) % mo;
}
ans = (ans * (2 * num + 1)) % mo;
}
printf("%lld", ans);
return 0;
}