我们在这里介绍一些关于n!的性质。

在计数问题中,经常需要用到n!。有必要了解n!在mod p下的一些性质。下面我们假设p是素数,n!=ape(a无法被p整除),并试图求解e和a mod p(把这个东西算出来可以很好的缩小组合数取模的数据)。e是n!中p因子的个数,因此可以使用下面的式子进行计算:

n/p+n/p2+n/p3+……

这个结论很显然,因为n/d和不超过n的能被d整除的个数相等。由于只需要对于pt<=n的t进行计算,因此复杂度O(logp n)。

接下来计算a mod p。首先计算n!=1*2*……*n的因数中不能被p整除的项的积。假设n=10,p=3则有

n!=1*2*4*5*7*8*10*(3*6*9)

1*2*4*5*7*8*10≡1*2*1*2*1*2*1(mod p)

从这个例子可以看出,不能被p整除的项的积等于(p-1)!(n/p)*(n mod p)!事实上根据威尔逊定理(代码的后面有证明),我们有(p-1)!≡-1(mod p)。因为除了1和p-1之外的项都可以和各自的逆元相乘得到1。

然后再处理一下可以被p整除的项就可以了(拿上面的例子来说就是3、6、9,都除以3之后还剩1、2)。具体的程序还是可以用递归来实现。

代码如下:

 int fact[MAXN];//fact里面存的是已经处理完毕的阶乘的值
int mod_fact(int n,int p,int &e){
e=;
if(n==)return ;
int res=mod(n/p,p,e);
e+=n/p;
if(n/p%==)return res*(p-fact[n%p])%p;//乘res递归处理是为了处理后面p的倍数
return res*fact[n%p]%p;
}

以下是威尔逊定理的证明:

首先我们需要先了解一下缩系:

若整数A1,A2,...,Am模n分别对应0,1,2,...,n-1中所有m个与n互素的自然数,则称集合{A1,A2,...,Am}为模n的一个缩系。

下面我们来证明下威尔逊定理:

威尔逊定理:当且仅当p为素数时:( p -1 )! ≡ -1 ( mod p)

必要性:如果p不是素数,那么它的正因数一定在1,2,3……(p-1)之中,所以gcd(p, (p-1)!)>1所以p一定是素数。

充分性:

若p是素数,取集合 A={1,2,3,...p -1}; 则A 构成模p乘法的缩系,即任意i∈A ,存在j∈A,使得:( i j ) ≡ 1 ( mod p )那么A中的元素是不是恰好两两配对呢? 不一定,但只需考虑这种情况

x^2 ≡ 1 ( mod p )

解得: x ≡ 1 ( mod p ) 或 x ≡ p-1 (mod p)

其余两两配对;故而( p - 1 )! ≡ 1*( p -1 ) ≡ -1 ( mod p)

n!(n的阶乘)的更多相关文章

  1. C语言 · 阶乘计算 · 基础练习

    问题描述 输入一个正整数n,输出n!的值. 其中n!=1*2*3*-*n. 算法描述 n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法.使用一个数组A来表示一个大整数a,A[0]表 ...

  2. Java 计算N阶乘末尾0的个数-LeetCode 172 Factorial Trailing Zeroes

    题目 Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in ...

  3. 关于for循环的几个小练习,例如奇数偶数,阶乘,求和等

    1 .100以内的奇数和偶数 var js = ""; var os = ""; for(var i=1;i<101;i++) { if(i%2 == 0 ...

  4. [LeetCode] Factorial Trailing Zeroes 求阶乘末尾零的个数

    Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in log ...

  5. 求单链表L各结点的阶乘之和(c语言)

    链表需要用到指针 阶乘需要用到递归 链表中的注意事项: 1.链表L是否等于NULL ----------是循环结束的条件 2.链表L->Data ---------取链表L中各个结点的值 3.L ...

  6. 洛谷 P2726 阶乘 Factorials Label:Water

    题目背景 N的阶乘写作N!,表示小于等于N的所有正整数的乘积. 题目描述 阶乘会变大得很快,如13!就必须用32位整数类型来存储,到了70!即使用浮点数也存不下了. 你的任务是找到阶乘最前面的非零位. ...

  7. js实现阶乘

    //while循环实现function calNum(n) { var product = 1; while(n > 1){//1*5*4*3*2,1*n*(n-1)*(n-2)*...*2 p ...

  8. 洛谷P1134 阶乘问题[数论]

    题目描述 也许你早就知道阶乘的含义,N阶乘是由1到N相乘而产生,如: 12! = 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x 11 x 12 = 479,001, ...

  9. Random随机类(11选5彩票)BigInteger大数据类(华为面试题1000的阶乘)

    先上Java Web图 为了简化叙述,只写Java代码,然后控制台输出 使用[Random类]取得随机数 import java.util.Random; public class Fir { pub ...

  10. 关于C++的递归调用(n的阶乘为例)

    C++,是入门编程界的一门初期的语言.今天我们浅谈一下有关C++的递归调用. 在没有继承,多态,封装之前,C++几乎看成是C语言,除了一些简单的输出和头文件. 具体代码实现如下: #include&l ...

随机推荐

  1. MySQL新建用户,授权,删除用户,修改密码总结

    首先要声明一下:一般情况下,修改MySQL密码,授权,是需要有mysql里的root权限的. 注:本操作是在WIN命令提示符下,phpMyAdmin同样适用. 用户:rdingcn 用户数据库:rdi ...

  2. 在线提取PDF中图片和文字

    无需下载软件,你就可以在线提取PDF中图片和文字,http://www.extractpdf.com/不仅可以获取本地PDF文档的图片和文字,还能获取远程PDF文档的图片和文字.如下图所示:结果本人测 ...

  3. 为git配置ssh

    git clone有两种方式,一种是http,一种是ssh. 配置ssh的好处是:在每次push代码的时候不需要输入密码. bash上生成秘钥: ssh-keygen -t rsa -C " ...

  4. Swift—do-try-catch错误处理模式-备

    Swift 1.x的错误处理模式存在很多弊端,例如:为了在编程时候省事,给error参数传递一个nil,或者方法调用完成后不去判断error是否为nil,不进行错误处理. let contents = ...

  5. LeetCode _ Gas Station

    There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You ...

  6. 功能:使用QQ号登陆,并加上微信和短信提醒,是否增量备份可选,阿里大鱼短信发送开发与测试,聚合数据(用JSON发短信,比较清楚)

    微博就可以,所以其它软件也可以http://desktop.weibo.com/ http://blog.csdn.net/jueblog/article/details/14497181http:/ ...

  7. Xamarin.Forms App Settings

    配合James Montemagno的Component [Settings Plugin],实现Xamarin.Forms的设置. 更新系统配置且不需要进行重启app. 方式一xml Xamarin ...

  8. 使用Userlock监控用户访问 增强学校网络安全

    随着网络技术的不断进步,一方面,拥有广泛教学资源的各大大中院校纷纷升级校园网络技术,保护学校的网络安全.另一方面,网络安全面临的威胁也层出不穷.面对来自网络内外的安全威胁,负责中小学.大学院校网络安全 ...

  9. How to Read an Engineering Research Paper

    How to Read an Engineering Research Paper William G. Griswold Department of Computer Science & E ...

  10. 就是一段程序,可以求出N个不等长列表中取N个元素形成的所有组合

    def get_result_in_vector(vector, N, tmp, tmp_result): """ :param vector:所有组合的拼接 :para ...