【[Violet]樱花】

就是化柿子

我们求

\[\frac{1}{x}+\frac{1}{y}=\frac{1}{n!} \]

的正整数解的个数

喜闻乐见的化柿子了

\[\frac{x+y}{xy}=\frac{1}{n!} \]

\[xy=xn!+yn! \]

\[xy-xn!=yn! \]

\[x=\frac{yn!}{y-n!} \]

所以这里的\(y\)显然是要大于\(n!\)

\(y=n!+c\)

那么

\[x=\frac{n!(n!+c)}{n!+c-n!}=\frac{n!(n!+c)}{c}=\frac{(n!)^2+n!c}{c} \]

\[x=\frac{(n!)^2}{c}+\frac{n!c}{c}=\frac{(n!)^2}{c}+n! \]

因为\(x\)也是正整数,就是说现在\(c\)\((n!)^2\)的约数

问题也就变成了求\(d((n!)^2)=\sum_{i|n}1\)

之后线筛一下暴力分解质因数就好了

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define re register
#define maxn 1000005
const LL mod=1e9+7;
inline int read()
{
    char c=getchar();
    int x=0;
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9')
        x=(x<<3)+(x<<1)+c-48,c=getchar();
    return x;
}
int n;
int f[maxn],p[maxn>>1];
int to[maxn],num[maxn>>1];
int main()
{
    scanf("%d",&n);
    f[1]=1;
    for(re int i=2;i<=n;i++)
    {
        if(!f[i]) p[++p[0]]=i,to[i]=p[0],num[to[i]]++;
        for(re int j=1;j<=p[0]&&p[j]*i<=n;j++)
        {
            f[p[j]*i]=1;
            if(i%p[j]==0) break;
        }
    }
    for(re int i=2;i<=n;i++)
    if(f[i])
    {
        int mid=i;
        int up=std::sqrt(i);
        for(re int j=1;j<=p[0]&&p[j]<=up;j++)
        {
            while(mid%p[j]==0) num[j]++,mid/=p[j];
            if(mid==1) break;
        }
        if(mid!=1) num[to[mid]]++;
    }
    LL ans=1;
    for(re int i=1;i<=p[0];i++)
        ans=(ans*(2*num[i]+1))%mod;
    std::cout<<(ans%mod);
    return 0;
}
posted @ 2019-01-02 12:16  asuldb  阅读(154)  评论(0编辑  收藏  举报