训练日志2

乘法逆元

对于缩系中的元素,每个数a均有唯一的与之对应的乘法逆元x,使得ax≡1(mod n)
一个数有逆元的充分必要条件是gcd(a,n)=1,此时逆元唯一存在
逆元的含义:模n意义下,1个数a如果有逆元x,那么除以a相当于乘以x。

下面给出求逆元的几种方法

1 循环找解法

给定模m和需要求逆的数x,直接暴力枚举1~m-1
检查是否有x*i=1(mod m)

这种算法可以应用与写暴力、对拍、模数较小,求逆次数少的情况
时间复杂度O(m)

2 扩展欧几里得算法

给定模数m,求a的逆相当于求解ax=1(mod m)
这个方程可以转化为ax-my=1
然后套用求二元一次方程的方法,用扩展欧几里得算法求得一组x0,y0和gcd
检查gcd是否为1
gcd不为1则说明逆元不存在
若为1,则调整x0到0~m-1的范围中即可

void ext_gcd(int a,int b,int &d,int &x,int &y){
    if (b==0){
        d=a;x=1;y=0;
        return;
    }
    ext_gcd(b,a%b,d,y,x);//回代
    y-=a/b*x;
}
int main(){
    scanf("%d%d",&m,&n);//求m关于n的逆元
    ext_gcd(m,n,d,x,y);
    printf("%d\n",(x+n)%n);
    return 0;
}

这种算法效率较高,常数较小,时间复杂度为O(ln n)

3 费马小定理及欧拉定理

在模为素数p的情况下,有费马小定理
a^(p-1)=1(mod p)
那么a^(p-2)=a^-1(mod p)
也就是说a的逆元为a^(p-2)

而在模不为素数p的情况下,有欧拉定理
a^phi(m)=1(mod m) (a⊥m)
同理a^-1=a^(phi(m)-1)

因此逆元x便可以套用快速幂求得了x=a^(phi(m)-1)

但是似乎还有个问题?如何判断a是否有逆元呢?
再求一次gcd判断是否互质吗?
这还不如直接用扩展欧几里得算法呢>_<

其实问题很简单,直接判断这是不是逆元就行了:
检验逆元的性质,看求出的幂值x与a相乘是否为1即可

这种算法复杂度为O(log2 n)
在几次测试中,常数似乎较上种方法大

比赛:

对于今天这次个人赛,做题太慌张,加上一直登不上和刷新不出来的问题(借口),以前的知识点有点淡忘,学过的东西拿过来用有点信心不足,结束后又在落谷找到原题做了做,不会的题补了些,还没有补完,全部是自己不会的zai看懂题解情况下,重新打的,当然还有会的,也都些了题解,数论看的有点跟不上进度了,接下来的时间里必须注重效率了。

猜你喜欢

转载自blog.csdn.net/sunpeishuai/article/details/81321638
今日推荐