[bzoj2721][Violet 5]樱花

题目链接

数论好(难)

题目要求求出$1/x+1/y=1/n!$ 中$x$和$y$的正整数解的个数

那么我们可以化简一下

很简单就可以化出$(x+y)n!=xy$

但是并没有化掉任何一个未知数,所以这玩意没用

在这个基础上再化简一下

因为$x,y$均为正整数且均$>n$

所以可以设$y=n!+k$

那么原式可化为$(x+n!+k)n!=x(n!+k)$

再整理一下(这里给出运算步骤)

$xn!+(n!)^2+kn!=xn!+kx$

$x=((n!)^2+kn!)/k$

$x=(n!)^2/k+n!$

于是我们向正解迈出了一大步

由题可知,$x,y,n!$均为整数,所以$k$也是整数(如果$k$不是整数,$x$也不会是整数)

然后由这个式子$x=(n!)^2/k+n!$我们可以知道,$k$一定是$(n!)^2$的一个因数,否则会不符合x是整数这个定义

且易得$x$和$k$是一一对应的

那么至此,这个问题就变成了,求$(n!)^2$的因数的个数

用一下欧拉筛法筛出质数,算出质数的每个幂对于我们所求的答案的贡献就可以了

#include <cstdio>
using namespace std;
#define mod 1000000007
#define N 1000010
#define ll long long
int p[N],v[N];
ll ans=1,cnt[N];
int n,tot=0;
void eular(){
    v[1]=1;
    for(int i=2;i<=n;i++){
        if(!v[i])v[i]=i,p[++tot]=i;
        for(int j=1;j<=tot;j++){
            if(p[j]>v[i]||p[j]*i>n)break;
            v[i*p[j]]=p[j];
        }
    }
}
int main(){
    scanf("%d",&n);
    eular();
    for(int i=1;i<=tot;i++){
        cnt[i]=0;
        for(ll j=p[i];j<=n;j*=p[i])cnt[i]+=n/j;
        cnt[i]%=mod;
    }
    for(int i=1;i<=tot;i++)ans=(ans*(cnt[i]*2+1))%mod;
    printf("%lld\n",ans);
    return 0;
}

感谢学长qzz的解惑qwq,学长的博客里也有这道题的题解如果我讲的不是很清楚,可以私信问我或者看下学长的博客=v=

猜你喜欢

转载自www.cnblogs.com/henry-1202/p/9357458.html