【数论】Miller_Rabin、线性求逆元

typedef long long LL;

Miller_Rabin素数测试

二次探测定理

如果 p p 是素数, x x 是小于 p p 的正整数,且 x 2 1 ( m o d p ) x^2\equiv1\pmod p ,那么要么 x = 1 x=1 ,要么 x = p 1 x=p-1
解读: 因为 x 2 m o d    p = 1 x^2\mod p=1 ,即 p x 2 1 p|x^2-1 ,也即 p ( x + 1 ) ( x 1 ) p|(x+1)(x-1)
由于 p p 是素数且 x < p x<p ,那么只可能是 x 1 x-1 能被 p p 整除(此时 x = 1 x=1 )或 x + 1 x+1 能被 p p 整除(此时 x = p 1 x=p-1 )。

要测试整数 n n 是否为素数,若 n n 是素数,根据费马定理,有 a n 1 m o d    n = 1 a^{n-1}\mod n=1
首先任选一个数做底数 a a
我们令 n 1 = d 2 R n-1=d\cdot 2^R ,其中 d d 是一个奇数,于是 a n 1 m o d    n = ( a d ) 2 R m o d    n = a d 2 R 1 a d 2 R 1 m o d    n a^{n-1}\mod n=(a^d)^{2^R}\mod n=a^{d\cdot 2^{R-1}}\cdot a^{d\cdot 2^{R-1}}\mod n
根据二次探测定理, a d 2 R 1 m o d    n a^{d\cdot 2^{R-1}}\mod n 要么等于 1 1 要么等于 n 1 n-1
如果 a d 2 R 1 m o d    n a^{d\cdot 2^{R-1}}\mod n 既不等于 1 1 也不等于 n 1 n-1 n n 一定不是素数,结束讨论。
如果 a d 2 R 1 m o d    n = n 1 a^{d\cdot 2^{R-1}}\mod n=n-1 ,我们认为 n n 是素数,结束讨论。
如果 a d 2 R 1 m o d    n = 1 a^{d\cdot 2^{R-1}}\mod n=1 ,继续讨论:

  • 根据二次探测定理, a d 2 R 2 m o d    n a^{d\cdot 2^{R-2}}\mod n 要么等于 1 1 要么等于 n 1 n-1 。……

上述讨论过程中,如果存在某个整数 k k ,使得 a d 2 k m o d    n = n 1 ( 0 k < R ) a^{d\cdot 2^k}\mod n = n-1 (0\leqslant k<R) ,我们就认为 n n 是素数,结束讨论。
或者,若 a d m o d    n = 1 a^d\mod n=1 n n 是素数。

这是一种不确定算法,每一次测试的准确率约为 75 % 75\%
若进行了 m m 次测试,时间复杂度为 O ( m log 3 n ) O(m\log_3n)

bool miller_rabin(LL n){
  if(n==2)return 1;
  if(n<2||!(n%2))return 0;
  LL d=n-1;int r=0;
  while(!(d&1))d/=2,r++;
  for(int i=1;i<=10;i++){
    LL a=rand()%(n-2)+2,x=Pow(a,d,n);
    for(int j=1;j<=r;j++){
      LL y=Mul(x,x,n);
      if(y==1&&x!=1&&x!=n-1)return 0;
      x=y;
    }
    if(x!=1)return 0;
  }
  return 1;
}

一些玄学操作:

  • n < 4759123141 n<4759123141 时,只需检测 a = 2 , 7 , 61 a=2,7,61 ,即可确保正确。
  • n < 2152302898747 n<2152302898747 时,只需检测 a = 2 , 3 , 5 , 7 , 11 a=2,3,5,7,11 ,即可确保正确。
  • n < 341550071728320 n<341550071728320 时,只需检测 a = 2 , 3 , 5 , 7 , 11 , 13 , 17 a=2,3,5,7,11,13,17 ,即可确保正确。

线性求逆元

a 1 = { 1 a = 1 ( p p a ) ( p m o d    a ) 1 m o d    p a > 1 a^{-1}=\begin{cases} 1&a=1\\ (p-\lfloor\frac pa\rfloor)(p\mod a)^{-1}\mod p&a>1 \end{cases}

证明:
显然 1 1 的逆元为 1 1
a > 1 a>1 时,已知 a a 1 1 ( m o d p ) a\cdot a^{-1}\equiv 1\pmod p ,其中 1 < a < p 1<a<p
k = p a , r = p m o d    a k=\lfloor\frac pa\rfloor,r=p\mod a ,那么 p = k a + r , 0 < r < a p=ka+r,0<r<a
则有 k a + r 0 ( m o d p ) ka+r\equiv 0\pmod p
两边同时乘以 a 1 r 1 a^{-1}r^{-1} 得到 ( k a + r ) a 1 r 1 0 ( m o d p ) (ka+r)a^{-1}r^{-1}\equiv 0\pmod p
k r 1 + a 1 0 ( m o d p ) k\cdot r^{-1}+a^{-1}\equiv 0\pmod p
转换得
a 1 = k r 1 m o d    p = p a ( p m o d    a ) 1 m o d    p = ( p p a ) ( p m o d    a ) 1 m o d    p \begin{aligned} a^{-1}&=-k\cdot r^{-1}\mod p\\ &=-\lfloor\frac pa\rfloor(p\mod a)^{-1}\mod p\\ &=(p-\lfloor\frac pa\rfloor)(p\mod a)^{-1}\mod p \end{aligned}

时间复杂度: O ( n ) O(n)

void make_inv(int*inv,int n,int p){
  inv[1]=1;
  for(int i=2;i<=n;i++)inv[i]=(p-p/i)*inv[p%i]%p;
}
发布了26 篇原创文章 · 获赞 13 · 访问量 4880

猜你喜欢

转载自blog.csdn.net/PHenning/article/details/89338803