【题目】
求方程\(\frac{1}{x}+\frac{1}{y}=\frac{1}{n!}\)的正整数解的组数,其中\(n\leq10^{6}\)。
解的组数,应模\(1e9+7\)。
输入格式:
输入一个整数\(n\)。
输出格式:
输出答案。
【Input】
1439
【Output】
102426508
【分析】
首先看到这个方程:
\[ \frac{1}{x}+\frac{1}{y}=\frac{1}{n!} \]
将左边通分后并将分子分母调换:
\[ \frac{xy}{x+y}=n! \]
再将\(x+y\)移到右边并两边同时乘以\(2\):
\[ x(2n!-y)+y(2n!-x)=0 \]
由此可得除非\(x\)和\(y\)都等于\(2n!\),否则其中必有一个是大于\(2n!\)的。那么我们假设\(x\)是大于\(2n!\)的,则易知\(x>2n!>y>n!\)。
假设\(y=n!+k\)(\(k\)为正整数),由上面的式子可以推出:
\[ \frac{x-2n!}{x}=\frac{n!-k}{n!+k} \]
于是:
\[ x=\frac{n!^{2}}{k}+n! \]
又\(x>2n!\)且\(x\)为正整数,所以
\[ \frac{n!}{k}>1 \]
这里我们就可以知道\(k\)必须取\(n!\)的约数,且\(k\)不能等于\(n!\)。于是我们只要求出\(n!\)的约数个数并减去\(n!\)这个约数即可,但我们之前是假设\(x>y\),所以约数还要乘\(2\)。
\(n!\)的约数要怎么求可以自行百度。
【代码】
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
bool prime[1000001];
void primes(){ //预处理所有质数
memset(prime,1,sizeof(prime));
prime[0] = 0;
prime[1] = 0;
for(int i=2;i<1000001;i++){ //埃氏筛
if(prime[i]){
for(int j=i+i;j<1000001;j+=i){
prime[j]=0;
}
}
}
}
int cal(int n,int p){ //用来计算n!的约数个数
if(n<p) return 0;
else return n/p+cal(n/p,p);
}
int main(){
primes();
int n;
scanf("%d",&n);
int i=2;
ll cnt=1;
while(i<=n){
if(prime[i])
cnt=(ll)cnt*((2*cal(n,i)+1)%mod)%mod; //一边计算,一边取模
i++;
}
printf("%lld",cnt); //输出答案
return 0;
}