乘法逆元
阿新 • • 發佈:2017-10-09
scan gcd sca log namespace main 要求 ron mod
占坑
為什麽要有乘法逆元呢?
當我們要求(a/b) mod p的值,且a很大,無法直接求得a/b的值時,我們就要用到乘法逆元。
我們可以通過求b關於p的乘法逆元k,將a乘上k再模p,即(a*k) mod p。其結果與(a/b) mod p等價。
#include<cstdio> #include <math.h> using namespace std; typedef long long ll; const int N = 1e5 + 5; int inv[N]; void exgcd(ll a,ll b,ll& d,ll& x,ll& y) {if(!b) { d = a; x = 1; y = 0; } else { exgcd(b, a%b, d, y, x); y -= x*(a/b); } } ll inv3(ll a, ll p)//擴展歐幾裏得 { ll d, x, y; exgcd(a, p, d, x, y); return d == 1 ? (x+p)%p : -1; } void inv2(int n, int p)//逆元打表法 { inv[1] = 1; for(int i=2; i<=n; ++i) { inv[i] = (ll) (p - p / i) * inv[p%i] % p; } } ll inv1(ll b,ll mod)//遞推法求逆元 { return b==1?1:(mod-mod/b)*inv1(mod%b,mod)%mod; } int main() { ll a,p; while(1) { scanf("%lld %lld",&a,&p); printf("%lld\n",inv1(a,p)); inv2(100,p);//100以內的數對P的逆元 printf("%lld\n",inv[2]); printf("%lld\n",inv3(a,p)); } }
乘法逆元