数论——洛谷 P1445 没占到1444的愤怒

来源:互联网 发布:linux 安装万兆网卡 编辑:程序博客网 时间:2024/05/16 09:09

https://www.luogu.org/problem/show?pid=1445
本来想考考fop_zz的,结果他直接A了哇..
大佬题解http://blog.csdn.net/fop_zz/article/details/73551108
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<bits/stdc++.h>#define Ll long longusing namespace std;const int N=1e6+5;bool com[N];int pri[N],tot,g[N],cnt[N];int n,m,mo=1e9+7;Ll ans;void make(){    for(int i=2;i<=n;i++){        if(!com[i])pri[++tot]=i,g[i]=tot;        for(int j=1;j<=tot;j++){            if(pri[j]*i>n)break;            com[pri[j]*i]=1;            g[pri[j]*i]=j;            if(i%pri[j]==0)break;        }    }}int main(){    scanf("%d",&n);    make();    for(int i=2;i<=n;i++)        for(int x=i;x!=1;x/=pri[g[x]])cnt[g[x]]++;    for(int i=1;i<=tot;i++)cnt[i]*=2;    ans=1;    for(int i=1;i<=n;i++)ans=ans*(cnt[i]+1)%mo;    printf("%d",ans);}
原创粉丝点击