• N!分解素因子及若干问题


    将N!表示成

    N! = p1^t1*p2^t2*…pi^ti…*pk^tk(其中p1,p2……pk是素数,1<N<= 10^6)

    显然很容易通过素数筛选求出pi,因为1<pi<=N,关键是如何快速地求出ti。

    我们先来看一下对于2这个素因子,把N!分成两部分,即奇偶两部分

    假设N是偶数

    N!

    =1*2*3*4*5……N

    =(2*4*6……) * (1*3*5……)

    因为有N/2个偶数,所以偶数部分可以提出N/2个2,

    =2^(N/2) * (1*2*3*……N/2) * (1*3*5*……)

    =2^(N/2) * (N/2)! * (1*3*5*……)

    看到了吗!神奇的事情发生了,N规模的问题转化成了N/2的问题了。上面假设了N是偶数,当然N是奇数时也是一样的,只要规定这里的除法是取整就可以了

    于是有递推公式 f(n,2) = f(n/2,2) + n/2,表示n!中2的个数。

    用同样的方法可以推出 f(n,p) = f(n/p,p) + n/p,表示n!中素数p的个数。

    于是有代码

    int f(int n,int p) { if(n==0) return 0; return f(n/p) + n/p; }

    将问题推广一下:

    问题1:N!的末尾有几个0?

    因为 10 = 2*5,所以只要知道N!有多少个2和多少个5,问题就解决了。Min(f(n,2),f(n,5)) 显然f(n,2)>f(n,5),所以问题就转化成了求f(n,5)。

    问题2:N!的转化成12进制之后,末尾有几个0?

    和问题一样,12=2*2*3,所以只要求Min(f(n,2)/2,f(n,3)),就可以了。

    问题3: 求组合数C(n,m)(mod p)

    C(n,m)=n!/(m!*(n-m)!) ,只要对分子和分母分别分解素因子,然后因为C(n,m)肯定是整数,所以C(n,m)肯定可以表示成p1^t1*p2^t2*......pi^ti的形式,只要拿分子素因子的幂减去分母对应的素因子的幂即可。好了,后面就简单了,二分快速幂取模......

    举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG
  • 相关阅读:
    7.9学习日志
    7.8学习日志
    7.7学习日志
    未命名 1
    未命名 1
    未命名 1
    【转】搭建Mac OS X下cocos2d-x的Android开发环境
    【转】如何高效利用GitHub——2013-08-28 22
    【转】GitHub删除一个仓库——2013-08-27 21
    【转】Cocos2d-x 2.x CCSprite 灰白图的生成(利用shader设置)——2013-08-27 21
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/4114163.html
Copyright © 2020-2023  润新知