
逆元:
概念:
若ab≡1 (mod m),则称a与b在模m的情况下互为逆元。记b=a,所以b又叫a的数论倒数。
我们介绍两种方法求解逆元:
1.费马小定理:
假如p是质数,且gcd(a,p)=1,那么 a^(p-1)≡1(mod p)。即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。
逆元:对于a和p,若a*b%p≡1,则称b为a%p的逆元。
除法的逆元,即求(a/b)%p的值
通常情况下,p均为质数,则公约数为1的情况基本都可以保证
由费马小定理得:
b^(p-1)%p=1 则:
b*b^(p-2)%p=1 两边同乘a/b,然后左右式交换得:
a/b=a/b*b*b^(p-2)%p 化简得:
a/b=a*b^(p-2)%p
此时的结果即为a/b的结果,取模得(a/b)%p;
2.扩展欧几里得
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
接下来我们重点用代码介绍扩展欧几里得求逆元。
首先引入快速幂与快速乘
ll qmul(ll a,ll b,ll m) //快速乘{ll ans=0;a%=m;b%=m;while(b){if(b&1){ans=(ans+a)%m;}a=(a+a)%m;b>>=1;}return ans;}
ll fast_pow(ll x, ll k, ll p){ //快速幂ll ret=1;x%=p;while(k>0){if(k&1){ret= qmul(ret, x, p);}k>>=1;x= qmul(x, x, p);}return ret;}
void extgcd(ll a,ll b,ll& d,ll& x,ll& y) //拓展欧几里得{if(!b){d=a;x=1;y=0;}else{extgcd(b,a%b,d,y,x);y-=x*(a/b);}}ll ModularInverse(ll a,ll b){ll d,x,y;extgcd(a,b,d,x,y);return d==1?(x+b)%b:-1; //返回的结果就是(1/a)mod(b)的结果// complete this part}
引入一道例题:蓝桥杯2019A组省赛E题

附解题代码:
#include<bits/stdc++.h>using namespace std;typedef long long ;qq fast_mul(qq x, qq y, qq p){qq ret=0;x%=p, y%=p;while(y>0){if(y&1){ret= (ret+x)%p;}y>>=1;x= (x+x)%p;}return ret;}qq fast_pow(qq x, qq k, qq p){qq ret=1;x%=p;while(k>0){if(k&1){ret= fast_mul(ret, x, p);}k>>=1;x= fast_mul(x, x, p);}return ret;}qq phi(qq n){qq ret= n;for(int i=2;i*i<=n;i++){if(n%i==0){ret= ret/i*(i-1);while(n%i==0) n/=i;}}if(n!=1){ret= ret/n*(n-1);}return ret;}qq get_p(qq n){for(qq i=2;i<=n;i++){if(n%i==0){return i;}}}int main(){qq n = (qq)1001733993063167141;qq d = 212353;qq C = 20190324;qq p,q,e,k;printf("n=%lld\n",n);p=get_p(n);q=n/p;printf("p=%lld, q=%lld\n",p,q);k=(p-1)*(q-1);printf("k=(p-1)*(q-1)=%lld\n",k);printf("phi(k)=%lld\n",phi(k));e=fast_pow(d,phi(k)-1,k);printf("e=d^(phi(k)-1)=%lld (mod k)\n",e);printf("d*e=%lld (mod k)\n",fast_mul(d,e,k));qq X=fast_pow(C,e,n);printf("X=C^e (mod n)= %lld\n",X);while(1)getchar();return 0;}
运行结果如下:

文章转载自WHICH工作室,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




