zoukankan      html  css  js  c++  java
  • 【51nod 1189】阶乘分数——阶乘质因数分解

    先对原式子进行一个变形:

    1/n!=1/x+1/y=(x+y)/xy--->n!*(x+y)=xy

    xy-(x+y)*n!=0--->xy-(x+y)*n!+n!2=n!2--->(x-n!)*(y-n!)=n!2

    那么如果我们能够求出n!2的约数个数,对于每个约数加上n!即可作为x或y。

    若n!=a1p1+a2p2+...+akpk,则n!的约数总数为∏(pi+1)

    因为是n!2,所以每个pi要乘上2.

    因为对于每个约数a,都必将有唯一的一个b与它对应使得a*b=n!,所以如果不考虑x和y的大小和重复关系的话答案就是约数个数。

    但是这里加上了限制条件,因此要除掉重复的部分,即需将答案加1除以2向下取整(加一是为了防止将完全平方数的平方根除去)

    对于n!的质因数分解,则应该先把n以内的质数筛出,求出每个质数的阶数即可。

    例:对10!分解质因数

    10以内的质数有2,3,5,7.

    2:10/2=5,10/4=2,10/8=1,阶数为2+5+1=8;

    3:10/3=3,10/9=1,阶数为3+1=4;

    5:10/5=2,阶数为2;

    7:10/7=1,阶数为1;

    所以10!=28*34*52*7.

    代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 typedef long long LL;
     4 const LL mod=1e9+7;
     5 const int N=1e6+10;
     6 int n,prime[N],cnt=0;
     7 bool vis[N];
     8 void make_prime(){
     9     for(int i=2;i<=n;i++){
    10         if(!vis[i])prime[++cnt]=i;
    11         for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
    12             vis[i*prime[j]]=1;
    13             if(i%prime[j]==0)break;
    14         }
    15     }
    16 }
    17 LL ans=1,ni=(mod+1)/2;
    18 int main(){
    19     scanf("%d",&n);
    20     make_prime();
    21     for(int i=1;i<=cnt;i++){
    22         LL p1=0;
    23         for(LL j=prime[i];j<=n;j*=prime[i])p1+=n/j;
    24         ans=(ans*(2*p1+1)%mod)%mod;
    25     }
    26     printf("%lld",(ans+1ll)*ni%mod);
    27     return 0;
    28 }
    51nod 1189
  • 相关阅读:
    SharePoint
    北京的雨
    SharePoint2003安装问题解答
    SharePoint安装时“Service Unavailable”的解决办法
    SharePoint安装程序常见问题解答和故障排查指南,做个参考:)
    银弹的看法
    vue组件注册方式
    vue中template和render的区别
    前端需要注意的SEO
    公众号中H5页面分享给好友或朋友圈自定义图片或文字
  • 原文地址:https://www.cnblogs.com/JKAI/p/7741105.html
Copyright © 2011-2022 走看看