洛谷 P1445 没占到1444的愤怒

来源:互联网 发布:ask软件 编辑:程序博客网 时间:2024/05/16 05:02

传送门
不得不吐槽一句,这题出题人真的很逗
以下我copy一段别人的题解:

1/x+1/y=1/n!
先通分
(x+y)/xy=1/n!
再化整数
xy-(x+y)*n!=0
然后配平
(n!)^2-(x+y)*n!+xy=(n!)^2
最后
(x-n!)*(y-n!)=(n!)^2
然后我们发现x,y都要是正整数;
所以原题可以变为
A*B=(n!)^2;
当A*B为正整数的时候x,y显然也是正整数;然后我们考虑x的取值,显然,若一个质数p有k个,那么x可以取p^0,p^1….p^k
共(k+1)种情况
乘法原理乘起来就可以了
而且显然,x确定后,y必然也会被确定
那么我们先可以欧拉筛;
求出每个数的最小质因数然后大力就好了;

其实就是质因数分解,枚举约数个数
直接贴代码了:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<cmath>#include<vector>#include<queue>#define ll long longusing namespace std;ll prime[500000];bool vis[1000001];ll n,cnt;void init(){    for(int i=2;i<=n;i++){        if(!vis[i]){            prime[++cnt]=i;        }        for(int j=1;j<=cnt&&(ll)i*(ll)prime[j]<=n;j++){            vis[i*prime[j]]=1;            if(i%prime[j]==0)break;        }    }}int main(){    scanf("%lld",&n);    init();    ll ans=1;    for(int i=1;i<=cnt;i++){        ll c=0;        for(ll j=prime[i];j<=n;j*=prime[i]){            c+=n/j;        }        ans*=(c*2+1);        ans%=1000000007;    }    printf("%lld",ans);    return 0;}