乘法逆元_三种方法
//方法一: 扩展欧几里得 (求逆元 调用mod_reverse函数) // 限定条件 a n 互质 log(n) // @a 数 // @n 模数 inline long long mod_reverse(long long a,long long n) { long long x,y,d=extend_gcd(a,n,x,y); if(d==1) { if(x%n<=0)return x%n+n; // 答案是负的要置为正的. else return x%n; } else return -1ll; } // 限定条件 a b 互质 // @a 是 这个数 // @b 是 模数 // @x 是 返回的逆元 返回-1 表示没有逆元 // @y 暂时不知道是什么... long long extend_gcd(long long a,long long b,long long &x,long long &y) { if(a==0&&b==0) return -1ll; if(b==0) { x=1ll; y=0ll; return a; } long long d=extend_gcd(b,a%b,y,x); y-=a/b*x; return d; } //方法二: 费马小定理 // 模数是一个质数 复杂度 log(n) // 原理, 当p是一个质数时,有 inv(a) = a^(p-2) % p; long long pwr4(long long a, long long k, long long jmod) { long long res = 1, base = a; while (k) { if (k&1) res = res * base % jmod; base = base * base % jmod; k >>= 1; } return res; } long long mod_reverse(long long a, long long n) { return pwr4(a, n-2, n); } //方法三: 欧拉定理 // 模数不是质数的情况 // 由a^φ(p)≡ 1(mod p) 得 a^(φ(p)−1)是a的逆元 // φ(p)是欧拉函数 // O(n)的时间可以递推出1~n在 mod p 意义下的逆元 // 没用过 所以先给出别人的代码 kuangbin大神板子也有代码. void inv3(LL mod)//线性递推求逆元 { inv[1]=1; for(int i=2;i<=mod-1;i++) { inv[i]=(mod-mod/i)*inv[mod%i]%mod; cout<<inv[i]<<" "; } }