同余小结

Posted aircastle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了同余小结相关的知识,希望对你有一定的参考价值。

同余

  • 定义:若整数$a$与整数$b$除以正整数$m$的余数相等,则称$a$,$b$模$m$同余,记为$a equiv b?( mod?m) $

  • 性质:

    • 1.反身性:$a≡a?(mod?m)$;
    • 2.对称性:若$a≡b?(mod?m)$,则$b≡a?(mod?m)$;
    • 3.传递性:若$a≡b?(mod?m)$,$b≡c?(mod?m)$,则$a≡c?(mod?m)$;
    • 4.同余式相加:若$a≡b?(mod?m)$,$c≡d?(mod?m)$,则$apm c≡bpm d?(mod?m)$;
    • 5.同余式相乘:若$a≡b?(mod?m)$,$c≡?d(mod?m)$,则$ac≡bd(mod?m)$。
  • 费马小定理:

    ? 若p为质数,则$a^{p}equiv a(mod?p) $ .

    推论:

    ? 若p为质数,则$a^{p-1}equiv 1(mod?p) $ .

  • 欧拉定理:

    ? 若正整数$a,n$ 互质,则$a^{phi(n)}equiv 1 ?(mod?n)$.

    推论:

    • 若正整数$a,n$ 互质,则对于任意正整数$b$,有$a^{b}equiv a^{b?mod ?phi(n)}?(mod?n)$.

      证明:设$b=q*phi(n)+r$,其中$0le rle phi(n)$,即$r=b?mod?phi(n)$.则:

      ? $a^{b}equiv a^{qphi(n)+r}equiv (a^{phi(n)})^{q} a^{r}equiv 1^{q}*a^{r}equiv a^{r}equiv a^{b?mod?phi(n)}?(mod?n)$.

    • 特别的,当$a,n$不一定互质且$b>phi(n)$时,有$a^{b}equiv a^{b?mod?phi(n)+phi(n)}?(mod?n)$.

  • 欧几里得算法:

    $forall a,bin N$ , $ b eq 0$

    $gcd(a,b)=gcd(b,a$ mod $b)$

    证明:

    ? 若$a<b$,则$gcd(b,a?mod?b)=gcd(b,a)$.
    ? 若$ageq b$,则

    ? 设$a=q imes b+r(0leq r<b)$.

    ? 令d为a,b的最大公约数,因为$d|a,d|b$,所以$d|(q imes b)$.从而推出

    ? $d|(a-q imes b)$,即$d|r$,所以a和b的最大公约数都为b与r的最大公约数.

    ? 代码实现:

      int gcd(int x,int y)
      {
          return y?gcd(y,x%y):x;
      }
  • 扩展欧几里得算法:

    对于任意整数$a,b?(b eq 0)$,一定存在一对整数 $x,y$,使得

    $ax+by=gcd(a,b)$.

    证明:

    构造方程 $bx_0+(a?mod?b)y_0=gcd(b,a?mod?b)$,则

    ?    $bx_0+[a-(a/b)*b]y_0=gcd(b,a?mod?b)$

    ?  $ay_0+b[x_0-(a/b)*y_0]=gcd(a,b)$

? 所以$x=y_0,y=x_0-(a/b)*y_0$.(ps: $a/b$中"/"为整除符号).

? 其中我们可以看出,求解$ax+by=gcd(a,b)$转化成了求解子问题$bx_0+(a?mod?b)y_0=gcd(b,a?mod?b)$,也 就是说,如果我们解决了子问题就可以解决当前的问题,于是我们考虑递归实现.由欧几里得算法可以看出最后一个 子问题为

? $a_0x+b_0=gcd(a_0,b_0)$(其中$a_0$为$a,b$的最大公约数,$b_0$为0)

显然有一组解为$x=1,y=0$,所以原问题的子问题显然有解,从而可以推出原问题的解一定存在.

代码实现:

#include<bits/stdc++.h>
using namespace std;
int gcd(int x,int y)
{
    return y?gcd(y,x%y):x;
}
void work(int a,int b,int &x,int &y,int &d)
{
    if(!b)
    {
        a=d;
        x=1,y=0;
        return;
    }
    work(b,a%b,x,y,d);
    int z=x;
    x=y,y=z-a/b*y;
}
int main()
{
    int a,b,x=0,y=0,d;
    cin>>a>>b;
    d=gcd(a,b);
    work(a,b,x,y,d);
    printf("%dx+%dy=%d
",a,b,d);
    printf("x=%d y=%d",x,y);
    return 0;
}
  • 乘法逆元:

    • 引入:目前为止,我们已经知道在加、减、乘运算下可以对于每一步直接取模,然而对于除法运算则不行。那么我们应该怎样迅速求出$frac{a}{b}$在模$p$ 意义下的值呢?

    • 定义:若整数$b,p$互质,且$b|a$,则存在一个$x$使得$frac{a}{b}equiv a?*?x?mod(p)$,称$x$为$b$在模$p$意义下的乘法逆元,记为$b^{-1}?(mod?p)$

    • 法一(若$p$为质数):

      因为$frac{a}{b}equiv a??b^{-1}equiv frac{a}{b}b*b^{-1} mod(p)$,则

      ? $b*b^{-1}equiv 1?(mod?p)$. $1$式

      因为$p$为质数,所以由费马小定理可得

      ? $b^{p-1}equiv 1?(mod?p)$.

      所以

      ? $b*b^{p-2}equiv 1?(mod?p)$ $2$式

      对比一、二式可以发现:

      ? $b^{-1}=b^{p-2} (mod?p)$

      因此,当$p$为质数时,$b$的乘法逆元为

      ? $b^{-1}=b^{p-2} mod?p$.

      所以,可以运用快速幂迅速求出$b$的乘法逆元。

    • 法二(若$p$不为质数):

      由法一得

      ? $b*b^{-1}equiv 1?(mod?p)$.

      设$b*xequiv 1(mod?p)$,则

      ? $p|b*x-1$.

      我们设$py=1-bx$,则

      ? $bx+py=1$.

      此时即求解一元二次方程

      ? $bx+py=1$.

      因为$b,p$互质,所以$gcd(b,p)=1$.由扩展欧几里得算法可以得到方程的解一定存在且可以由扩欧求出。

    • 法三(线性求解逆元):

      前两种都是求单个数的逆元,但如果要求多个数的逆元时,我们可以采用线性做法。

      求$i$的逆元:

      令$p=k*i+r$,其中($0le r<i$),即$k$为$p/i$的商,$r$为余数.则有

      ? $pequiv 0?(mod?p)$

      $Leftrightarrow$ $k*i+requiv 0?(mod?p)$

      同余式左右两边同时乘以$i^{-1},r^{-1}$,则

      ? $k*r^{-1}+i^{-1}equiv 0?(mod?p)$

      $Leftrightarrow$ $i^{-1}equiv -k*r^{-1}?(mod?p)$.

      设$f_i$表示$i$在模$p$意义下的逆元,则有

      ? $f_i=-(p/i)*f_{p?mod?i}?(mod?p)$ (ps: $a/b$中"/"为整除符号).

      为了保证$f_ige 0$,再进行一步操作:

      ? $f_i=p-((p/i)*f_{p?mod?i}?mod?p)?(mod?p)$.

      就可以$O(n)$求出$x$的逆元.

    • 法四(线性求解阶乘逆元):

      设$f_i$表示$i!$在模p意义下的逆元,则有

      ? $f_i=i!^{-1}=frac{1}{i!}$

      所以

      ? $f_i=frac{1}{(i+1)!}(i+1)=f_{i+1}(i+1)$.

      因此,我们只需要求出$n!$的逆元,就可以倒序求解$1!,2!,3!...(n-1)!,n!$在模p意义下的逆元了.

以上是关于同余小结的主要内容,如果未能解决你的问题,请参考以下文章

逆元小结

线性同余法产生1000个随机数

同余方程

线性同余法的伪随机数

HDU - 5776 同余(思维)

HDU - 5776 同余(思维)