• 【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
  • 相关阅读:
    PipeCAD Grid
    Java -- MyBatis学习笔记11、PageHelper
    Java -- MyBatis学习笔记10、主配置文件
    Java -- MyBatis学习笔记9、动态SQL
    Java -- MyBatis学习笔记8、模糊查询like
    Java -- MyBatis学习笔记7、# 和 $的区别
    Java -- MyBatis学习笔记6、参数传递
    Java -- MyBatis学习笔记5、getMapper
    Java -- MyBatis学习笔记4、简单CURD
    Java -- MyBatis学习笔记3、输出日志
  • 原文地址:https://www.cnblogs.com/JKAI/p/7741105.html
Copyright © 2020-2023  润新知