模运算与逆元

前两天做了一道题是关于模运算的。模就是我们常说的取余。例如4 % 6 = 4,6 % 4 = 2。模运算的运算规则和四则运算类似。但是除法除外,有关这一点我们在后面会详细讲。

首先我们先介绍一下模运算的运算规则:

(a + b) % p = (a % p + b % p) % p
(a - b) % p = (a % p - b % p) % p
(a * b) % p = (a % p * b % p) % p
(a ^ b) % p = ((a % p) ^ b ) % p
模运算的结合律:
((a + b) % p + c) % p= (a + (b + c) % p) % p
((a * b) % p * c) % p = (a * (b * c) % p ) % p
交换律:
(a + b) % p = (b+a) % p
(a * b) % p = (b * a) % p
分配率:
((a +b) % p * c) % p = ((a * c) % p + (b * c) % p) % p
上文我们可以看出,除了除法之外模运算的运算规则和四则运算类似。关于模运算的除法运算我们需要了解一个概念叫逆元。
逆元是指指数学领域群G中任意一个元a,都在G中有唯一的逆元a‘,具有性质a×a'=a'×a=e,其中e为该群的单位元。在模运算中,单位元便是1。举个例子,求4关于7的乘法逆元,就是求一个数x,使4 * x % 7 = 1。下面我们来介绍求取逆元的算法:
第一种方法是循环求解法:给定模m和数x,在1 ~ m – 1中检查是否有x * i mod m = 1。

第二种方法是扩展欧几里得算法。欧几里得算法的依据是最大公约数定理:对任意的非负整数a和任意正整数b,gcd(a,b) = gcd(b,a mod b).
扩展欧几里得算法为:

Extend-Ecuclid(a,b):
If b == 0:
Then return(a,1,0)
(d1,x1,y1) = Extend-Ecuclid(b,a mod b)
(d,x,y) = (d,y1,x1-[a / b] * y1)
Return (d,x,y)
这里x是a的系数,y是b的系数。
在求a * x mod m = 1时,就是求a * x + m * y = 1的过程。那么我们需要的就是a的系数x。因此可以用欧几里得算法求解。欧几里得算法的C++过程为:

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);
    ext_gcd(m,n,d,x,y);
    printf("%d\n",(x+n)%n);
    return 0;
}



  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值