数论好题
2721: [Violet 5]樱花

简化版:
求方程 $ \dfrac{1}{X}+\dfrac{1}{Y}= \dfrac{1}{N!}$ 的正整数解的组数,其中 $ N≤10^6 $ 。
解的组数,应模$1e9+7$。

Output:

$1439$
Sample Output:
$102426508$
HINT:

题解:
STEP1:
尝试化简该式子?
可以注意到 $X>N!$
那么可以设 $X = (N!+a)$
代入原式得:
$\dfrac{1}{N!+a}+\dfrac{1}{Y}= \dfrac{1}{N!}$
通分:
$Y×N!+N!\times(N!+a)=Y×(N!+a)$
化简:
$(N!)^2+aN!=aY$
$Y=\dfrac{(N!)^2}{a}+N!$
$a|(N!)^2$ 时$Y$为整数。
任意一个能整除$(N!)^2$的$a$可以确定一个$Y$从而确定$X$也就是该 $ \dfrac{1}{X}+\dfrac{1}{Y}= \dfrac{1}{N!}$方程的一组解。
$∴$ 答案就是$(N!)^2$的约数个数。
STEP2:
但是如何求$(N!)^2$的约数个数?
根据算数基本定理的推论:
$(c1+1)×(c_2+1)×…×(c_m+1)=\prod{i=1}^{m}(c_i+1)$
$c_i$是分解出质因数的指数。
Code
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 
 | #include<cstdio>#define ll long long
 using namespace std;
 inline ll read(){
 ll ans=0,f=1;char ch=getchar();
 while(ch<'0'||ch>'9'){if(ch=='-'){f=-1;}ch=getchar();}
 while(ch>='0'&&ch<='9'){ans=ans*10+ch-48;ch=getchar();}
 return ans*f;
 }
 void write(ll x){
 if(x<0){putchar('-');x=-x;}
 if(x>9){write(x/10);}
 putchar(x%10|48);
 }
 const int MOD=1e9+7;
 const int N=1e6;
 int n;
 int cnt,prime[N+5];
 bool book[N+5];
 inline void getprime(){
 book[1]=true;
 for (int i=2;i<=N;i++){
 if(!book[i]){
 prime[++cnt]=i;
 }
 for (int j=1;j<=cnt;j++){
 if(i*prime[j]>N){
 break;
 }
 book[i*prime[j]]=1;
 if(i%prime[j]==0){
 break;
 }
 }
 }
 }
 int ct[N+5];
 ll ans=1;
 int main(){
 n=read();
 getprime();
 for (int k=2;k<=n;k++){
 int t=k;
 for (int i=1;i<=cnt && prime[i]*prime[i]<=t;i++){
 while(t%prime[i]==0){
 ct[prime[i]]++;
 t/=prime[i];
 }
 }
 if(t>1){
 ct[t]++;
 }
 }
 for (int i=1;i<=cnt;i++){
 ct[prime[i]]*=2;
 ct[prime[i]]%=MOD;
 ans=(ans*(ct[prime[i]]+1))%MOD;
 }
 write(ans);
 return 0;
 }
 
 |