1. 程式人生 > >同餘與逆元

同餘與逆元

  • 同餘

    • 前置知識 ————擴充套件歐幾里得定理

    • 什麼是同餘

      對於兩個數a,b,它們對於p取模結果相同,那麼就稱a和b在對p取模意義下同餘
    • 公式表達a≡b(mod)p

    • 如何求一個數的同餘

      利用擴充套件歐幾里得定理
      我們將該公式轉化一下 -> a%p == b%p
      再變一下 -> a%p - b%p == 0
      再變一下 -> a%p + (-b%p) ==0
      誒,這個時候我們可以發現這個和擴歐的公式好像啊(ax+by==c)
      那麼是不是將其看成擴歐就可以解決了呢
      事實是————是的
      但是我們知道可以用擴歐求出一個同餘來了,但是好像還是不知道怎麼求,也不知道同餘可以幹什麼啊

      事實上,在平常的寫題中沒有係數的同餘都是很少出現的,一般同餘是這麼出現的-----
      ax≡b%p 它會告訴你一個係數再讓你去求解
      更特殊的,b會等於1,這個時候,就扯到逆元上了
  • 逆元

    • 什麼是逆元

      形如ax≡1%p的x我們就稱x是a的一個逆元,即a乘以x後mod p的答案是1
    • 逆元有什麼用

      在部分對一個很大的數字取模防止答案爆long long以至於表達不出來的題目中,有時會發現會用到除法,可是用整數除法會有問題啊,那怎麼辦呢又是那怎麼辦呢
      這個時候逆元就派上用場了
      我們發現,ax mod p ==1 時,這個x等於 $\frac{1}{a}$時就是一個最明顯的滿足條件的逆元,可是$\frac{1}{a}$不是一個整數啊,那怎麼辦呢?

      實際上,一個數對於另一個數取模時,它的逆元是有無數個的,只不過$\frac{1}{a}$是最小的一個,也就是說,還會有ay mod p == 1的存在,
      而這個時候,由於要對p取模,那麼我們的a乘以x和乘以y的效果都是一樣的,所以$\frac{1}{a}$可以被另一個常數y所代替,再想開一點,是不是所有的常數在對p取模時乘以$\frac{1}{a}$時都可以被y所代替呢, 由於p是不變的,所以這個結論是正確的

    • 如何求逆元

    • 求逆元有三種方式
      前面說過,有一種是可以用ex_gcd來求的
      另外兩種分別是費馬小定理(有侷限性,但是非常簡單)和線性推逆元(線性的去求逆元,適用於大規模求逆元)
      • ax ≡ 1 mod b

      • ax%b == 1
      • #### ax-ax/b*b==1
      • 設y為ax/b,ax + (b(-y)) == 1
      • 以下y為-y
      • ax + by == gcd(a,b)
      • #### gcd(a,b) == gcd(b,a%b) == gcd(b,a-a/b*b)
      • ax + by == gcd(b,a-a/bb) == bx'+(a-a/bb)y'
      • #### ax + by == bx' + ay' - a/b*by'
      • #### ax + by == ay' + b(x'-a/b*by)
      • x = y',y = x' - ab / by
      • 由此,我們可以得出求一個數的逆元的公式了
  • 總結

    • 同餘是當兩個數都模一個p它們的餘數相同,那麼我們就稱這兩個數同餘
      • 逆元是同餘的一種常見特殊情況
      • 對於求逆元,首先要知道逆元有什麼用:
      • 逆元是在取模運算中可以用乘法代替除法的巧妙工具
    • code:

       void ex_gcd(int a,int b,int &x,int &y)
      {
          if (b==0){x=1,y=0;return;}
          ex_gcd(b,a%b,x,y);
          int tmp=x;
          x=y,y=tmp-a/b*y;
      }