Lucas定理:线性求所有逆元的方法

Miskcoo's Space,版权所有丨如未注明,均为原创
转载请注明转自:http://blog.miskcoo.com/2014/09/linear-find-all-invert

主要绕过费马小定理来证明lucas定理,挺有意思..此外设置多进制计算机可以通过移位运算直接加快多进制运算的速度。

1.Lucas定理

Lucas定理详解

Lucas定理解决的问题是组合数取模。数学上来说,就是求 (nm)modp

这里n,m

可能很大,比如达到 1015 ,而 p 109

以内。显然运用常规的阶乘方法无法直接求解,所以引入Lucas定理。

Lucas定理

n

m 写成 p 进制数的样子(如果长度不一样把短的补成长的那个的长度):
n=(a0a1ak)p
m=(b0b1bk)p

那么:
(nm)ki=0(aibi)modp

证明
如果把Lucas定理从递归的角度理解,它其实是这样的:
n=ap+b,m=cp+d,(b,d<p,a=np,c=mp)(nm)(ac)(bd)

这个定理的一个很巧妙的证法是通过二项式定理来说明上面的式子是成立的。

首先,对于任意质数pp,有:
(1+x)p1+xpmodp

其证明可以由费马小定理(xpxmodp) |p)

直接得出:
(1+x)p1+x
xpx
所以 (1+x)p1+x1+xp

(当然同样也有(a+b)pap+bpmodp

,具体为什么你可以拆开前面的式子,将其除 ap bp 项外的所有项的系数好好研究一下(其实就是杨辉三角的第p层),可以发现把对称项系数分别合并后都能整除 p

利用这个性质,我们证明Lucas定理:
(1+x)n=(1+x)npp(1+x)b=(1+xp)np(1+x)b=i=0k(npi)xpij=0k(bj)xj

考察等式左右两边xmxm的系数,可以发现:
=(nm)=(npi)(bj),(pi+j=m,j<p)=(npmp)(bd)

所以上面的式子成立,证明完毕。

如果不算预处理什么的,算法时间复杂度为O(logpn)

。如果能够支持预处理,那么就加一个 O(p) ,要不就用快速幂,乘上 O(logp)

2. 线性求所有逆元的方法

前几天在看 lucas 定理的时候发现要求 1, 2,,p1modp 的逆元,然后就看到了一个 Θ(n)

的做法发现太神了,虽然想起来是挺简单的

这个做法实际上是这样的,首先 111(modp)

然后我们设 p=ki+r, r<i, 1<i<p

再将这个式子放到modp

意义下就会得到

ki+r0(modp)

两边同时乘上 i1r1

就会得到

kr1+i1i1i10kr1pi(pmodi)1(modp)(modp)(modp) 

于是就可以从前面推出当前的逆元了,代码也就一行

A[i] = -(p / i) * A[p % i];
Related posts:

猜你喜欢

转载自blog.csdn.net/wishchin/article/details/80925964