• n!mod p 的求法 数学


    今天在教室看了一上午的白书,发现其中的这一章很有意思,用各种神奇的解法来做一个没有任何用的阶乘取模。

    首先我们直到如果p<n的话,取模的结果肯定是0对吧,如果p>n他又叫我们直接预处理出来,真的搞不懂。

    然后就是他给的神奇方法:

    在计数问题中,经常需要用到n!。在学完前面的介绍之后,有必要了解n!在mod p下的一些性质,下面我们假设p是素数,n!=a pe(a无法被p整除),并试图求解a mod p和e。

    e是n!能够迭代整除p的次数,因此可以使用下面的式子计算。

    n/p+n/p2+n/p3+......

    这个结论很显然,因为n/d和不超过n的能被d整除的正整数的个数相等。由于只需要

    对于pt<=n的t进行计算,因此复杂度是O(logpn)。

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

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

    =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。所以该项可以简化成-1(n/p)*(n mod p)!。

    接下来,计算可以被p整除的项的积。很简单,就是1,2,3....n/p。因此,问题的范围就由n缩小到了n/p。如果预处理出0<=n<p范围中n! mod p的表,就可以在O(logpn)时间内算出答案。

    int fact[MAX];//预处理阶乘表
    
    //分解n!=ape,返回a mod p。
    int mod_fact(int n,int p,int& e)
    {
    	e=0;
    	if(n==0)
    		return 1;
    
    	int res=mod_fact(n/p,p,e);
    	e+=n/p;
    
    	if(n/p&2!=0)
    		return res*(p-fact[n%p])%p;
    	return res*fact[n%p]%p;
    }
    

    PEACE
  • 相关阅读:
    滚动 冻结 div demo
    JavaScript去除字符串两边空格trim
    window.showModalDialog以及window.open用法简介
    转: 分享我创业4年失败的经历
    [转]JavaScript break跳出多重循环
    showModalDialog 传值及刷新
    防止文字撑开表格,强制表格大小
    带记忆功能的表单
    checkbox 全选
    asp教程:关于jquery跨域彻底的解决方法
  • 原文地址:https://www.cnblogs.com/gshdyjz/p/7498471.html
Copyright © 2020-2023  润新知