一、除法取模逆元
如果我们要通过一个前面取过模的式子递推出其他要取模的式子,而递推式里又存在除法
那么一个很尴尬的事情出现了,假如a[i-1]=100%31=7 a[i]=(a[i-1]/2)%31
a[i]=50%31=19 ,但我们现在只知道a[i-1]=7,如何计算出a[i]=19呢? a[i]=(7/2)%31=3?
其实本来是100是整除2的,但是对31取模后就不能整除了,所以我们要求出在mod 31意义下2的逆元是多少
口算可得,2*16%31=1,所以2的逆元就是16,所以a[i]=(a[i-1]*inv(2))%31=7*16%31=19
那么通过逆元我们就得到了正确的结果。
a/b mod m 等价计算为 a*k mod m (k是b的模m乘法逆元)
证明过程:
由于k是b的模m乘法逆元。 即 b*k mod m == 1
b*k = xm + 1
k = (xm+1) / b
则 a * k mod m = a * (xm + 1) / b mod m
= a/b * (xm + 1) mod m
= xa/b * m mod m + a / b mod m
= a / b mod m
所以以上两式等价。
二、扩展欧几里得
欧几里得定理, gcd(a, b)用来求a,b的最大公约数。 gcd(a, b) = gcd(b, a%b) = gcd
扩展欧几里得定理:
对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by。
1 void gcd(int a, int b, int &d, int &x, int &y) 2 { 3 if(!b) { d = a; x = 1; y = 0; } 4 else { gcd(b, a%b, d, y, x); y -= x*(a/b); } 5 }