有理分式的取模運算
阿新 • • 發佈:2020-12-19
引出
一些取模的基本運算:
(a+b)%p=(a%p+b%p)%p 對
(a-b)%p=(a%p-b%p)%p 對
(a×b)%p=(a%p×b%p)%p 對
(a/b)%p=(a%p/b%p)%p 錯
一些符號的說明
≡: a≡b(mod p) 表示 a和b分別模p,餘數相同,即a和b對p取模同餘
乘法逆元的定義
若在mod p意義下,對於一個整數a,有a*p≡1(mod p),那麼這個整數x即為a的乘法逆元,同時a也為x的乘法逆元
充要條件
a存在模p的乘法逆元的充要條件是gcd(a,p)=1,即a與p互質
有理分數的取模
求取(a/b)%p 等同於 a(b的逆元)%p
證明:
設b的x的逆元為x,即b
對於式① (a/b)%p=m
①×b得② a%p=mb %p
②×x得③ ax=mbx %p
即 ax≡mbx (%p)
又因為 bx≡1(%p)
所以 ax≡m(%p)
因此 (a/b)%p=m 也就是 ax≡m(%p)
逆元的求解
費馬小定理:假如a是一個整數,p是一個質數,那麼
1.如果a是p的倍數,a^p≡a(%p)
2.如果a不是p的倍數,a^(p-1)≡1(%p)
又因a存在模p的乘法逆元的充要條件是gcd(a,p)=1,所以a肯定不是p的倍數,因此
a^(p-1)≡1(%p)
即 aa^(p-2)≡1(%p) a^(p-2)就是a的乘法逆元
a%p
有理分數的取模運算
綜上所述,得出結論:
(b/a)%p=(ba的逆元)%p=(ba^(p-2))%p
程式碼實現
程式碼出自:https://www.jianshu.com/p/d0a083a7e4c1
public class Mod { public static final long MOD = 1_000_000_007; /** * 模乘 * @param x * @param y * @return x * y % MOD */ public static long mul(long x, long y) { return ((x % MOD) * (y % MOD)) % MOD; } /** * 模加 * @param x * @param y * @return (x + y) % MOD */ public static long add(long x, long y) { return ((x % MOD) + (y % MOD)) % MOD; } /** * 模快速冪 * @param x * @param n * @return x^n % MOD */ public static long quickPower(long x, long n) { if (n == 0) return 1; if (n == 1) return x % MOD; long tmp = quickPower(x, n >> 1); return (n & 1) == 0 ? mul(tmp, tmp) : mul(x, mul(tmp, tmp)); } /** * 分數求模 * 費馬小定理 a^(p-1) mod p = 1 mod p * a * a^(p-2) mod p = 1 mod p * a^(p-2) mod p = a^(-1) mod p * (b/a) % p = b * a^(-1) % p = b * a^(p-2) % p * @param a 分母 * @param b 分子 * @return (b/a) % MOD */ public static long fractionMod(long a, long b) { return mul(b, quickPower(a, MOD-2)); } }