处理模运算

模运算规则

基本运算法则
  • 加法运算法则: (a+b)%c=(a%c+b%c)%c
  • 减法运算法则: (ab)%c=(a%cb%c)%c
  • 乘法运算法则: (ab)%c=(a%cb%c)%c
  • 指数运算法则: (ab)%c=((a%c)b)%c
  • 除法运算法则:需要求逆元,我们后面讲
交换律
  • 加法交换律: (a+b)%c=(b+a)%c
  • 乘法交换律: (ab)%c=(ba)%c
结合律

-加法结合律:

((a+b)%d+c)%d(a+(b+c)%d)%d=(((a+b)%d)%d+c%d)%d=((a+b)%d+c%d)%d=(a+b+c)%d=(a%d+((b+c)%d)%d)%d=(a%d+(b+c)%d)%d=(a+b+c)%d

-乘法结合律:
((ab)%dc)%d(a+(b+c)%d)%d=(((ab)%d)%dc%d)%d=((ab)%dc%d)%d=(abc)%d=(a%d((bc)%d)%d)%d=(a%d(bc)%d)%d=(abc)%d

分配率

((a+b)%dc)%d=((a+b)%d%dc%d)%d=((a+b)%dc%d)%d=((a+b)c)%d=(ac+bc)%d=((ac)%d+(bc)%d)%d

同余运算

定义

两个整数 a , b关于 p 同余,定义为a%p=b%p,记为 ab(modp)

同余运算法则
  • 加法法则 : ab(modp)(a+c)(b+c)(modp)
  • 乘法法则 : ab(modp)(ac)(bc)(modp)
  • 混合法则:如果 ab(modp) 并且 cd(modp) ,那么可以得出如下几条结论:
    • (a+c)(b+d)(modp)
    • (ac)(bd)(modp)
    • (ac)(bd)(modp)

模运算应用

求最大公约数 gcd(a,b)
1. 更相减损法

这个算法最早记载于中国的数学名著《九章算术》中,其主要的思路:假设 x=gcd(a,b) , 显然我们知道 a%x=0 b%x=0 , 根据同余运算法则 (ab)%x==0 . 假设 gcd(a,b) 是方程组的解

{a%xb%x=0=0 

显而易见, gcd(a,ab) 也是方程组的解
{a%x(ab)%x=0=0 

我们可以推出如下结论: gcd(a,b)=gcd(a,ab) . 于是我们找到了求最大公约数的解法。

int jiuzhang_gcd(int a, int b) {
    while (a != b) {
        if (a > b) {
            a -= b;
        } else {
            b -= a;
        }
    }
    return a;
}
2. 辗转相除法

辗转相除法又叫Euclidean 算法,是著名数学家欧几里得发明的,其基本的思想是,假设我们要求的是整数 a b的最大公约数 x ,且这两个数满足如下关系:

aba/b=mx=nx=cr

很容易得出如下结论:

r=acb=mxcnx=Cx

所以,gcd(a,b) = gcd(a%b, b).

int euclidean_gcd(int a, int b) {
    while (max(a,b) % min(a,b) != 0) {
        if (a > b) {
            a %= b;
        } else {
            b %= a;
        }
    }
    return min(a,b);
}
3. 扩展辗转相除法

问题描述:假定存在两个互素的正整数 a b,求解方程 ax+by=1 .
思想:由于 a b互素(事实上,如果 a b不互素,那么上述方程无解),所以 gcd(a,b)=1 , 于是 ax+by=gcd(a,b) 。为了求解上述方程,我们令

{ab=b=a%b

并求解下面方程的解:
ax+by=gcd(a,b)bx+(a(a/b)b)y=gcd(a,b)ay+b(x(a/b)y)=gcd(a,b)

只要我们求出上述方程的解(x’,y’), 经过转换我们就可以求出原始方程的解(x,y), 转换的方程如下
{xy=y=x(a/b)y 

经过迭代,最终会出现求解 1x+0y=gcd(1,0) 的情况,这正是这个解法的终止条件。

void ext_gcd(int a, int b, int &x, int &y) {
    if (b != 0) {
        int xx, yy;;
        ext_gcd(b, a%b, xx, yy);
        x = yy;
        y = xx - (a / b) * yy;
    } else {
        x = 1;
        y = 0;
    }
}
求逆元
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值