乘法逆元的求法(4种)

一、扩展欧几里得求逆元

板子O(logN):

 1 #include<bits/stdc++.h>
 2 typedef long long ll;
 3 ll exgcd(ll a,ll b,ll &x,ll &y) {
 4     if(!b) {
 5         x=1,y=0;
 6         return a;
 7     }
 8     ll res=exgcd(b,a%b,y,x);
 9     y-=a/b*x;       ///x=x1,y=x1-a/b*y1   x1,y1代表下一状态
10     return res;
11 }
12 int main()
13 {
14     ll a,p,x,y;  ///扩展欧几里得计算a的逆元(mod p)
15     scanf("%lld%lld",&a,&p);
16     ll d=exgcd(a,p,x,y);
17     printf(d==1?"%lld":"-1",(x+p)%p);///最大公约数不为1,逆元不存在,输出-1
18     return 0;
19 }
View Code

二、费马小定理求逆元(p为素数)

板子O(logp):

 1 #include<bits/stdc++.h>
 2 typedef long long ll;
 3 ll quickpowmod(ll a,ll b,ll mod) {
 4     ll ans=1;
 5     while(b) {
 6         if(b&1) ans=(ans*a)%mod;
 7         b>>=1;
 8         a=(a*a)%mod;
 9     }
10     return ans;
11 }
12 int main()
13 {
14     ll a,p;  ///费马小定理计算a的逆元(mod p)
15     scanf("%lld%lld",&a,&p);
16     ll inva=quickpowmod(a,p-2,p);
17     printf("%lld",inva);
18     return 0;
19 }
View Code

猜你喜欢

转载自www.cnblogs.com/wuliking/p/11247707.html
今日推荐