轉自:http://jaskell.blogbus.com/logs/3249971.html
一、同余
我們來了解一下什么是“同余”。簡單來說就是,如果兩個數都除以某個數能夠有相同的余數,那么我們就說這兩個數“同余”。不過這次我們用嚴謹的數學概念來表述:
兩個整數 a,b,若它們除以整數 m 所得的余數相等,則稱 a,b 對于模 m 同余
記作 
讀作 a 同余于 b 模 m ,或讀作 a 與 b 關于模 m 同余。
比如 
我們再來了解一下相關的性質:
- 如果
,那么 m | (a − b) ,這里 m | (a − b) 表示 (a − b) 能被 m 整除
- 如果
,
, 那么
- 如果
,
, 那么
,
,
,
- 如果
, 那么
有了這些性質,判斷兩個數是否同余就可以用更簡單的方法了。根據性質一,原來我們需要判斷 (a mod m) == (b mod m)
是否為真,現在就可以直接判斷 (a - b) mod m == 0
是否為真了。這樣就把其中一次求余運算變為減法運算了。一般來說減法要比除法更容易在計算機上實現,運算速度也更快。
二、求余 (a * b * c * d) mod m = ?
由于計算機表示一個整數通常用 32bit 。而大量連乘運算則可能會導致整數溢出,這時我們就要利用求余一些性質來進行處理了。把以上式子轉換為:
已知: (a * b) mod m == ((a mod m) * b) mod m
所以: (a * b * c * d) mod m = ((((((a mod m) * b) mod m) * c) mod m) * d) mod m
這樣就把連乘運算分解了,每次可以先進行求余運算然后再進行乘法運算。