标签:欧几里得 等价 print log 结果 mat strong printf const
占坑
为什么要有乘法逆元呢?
当我们要求(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)); } }
标签:欧几里得 等价 print log 结果 mat strong printf const
原文地址:http://www.cnblogs.com/aiguona/p/7642683.html