ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

计算机基础-取模

2021-12-11 15:00:11  阅读:230  来源: 互联网

标签:取模 计算机 欧几里德 基础 算法 3.2 ax gcd


引言.

在做算法题的过程中,经常需要取模操作,对结果模上1e9+7或者1e9+9或者998244353。但有时会发现题目A不了最后是取模的问题,为了在日后的题目完成过程中避免因取模而出错,因此整理一下取模相关的知识。

文章目录

1. 取模运算和取余运算:

这一部分的内容介绍取模和取余的区别,是作为基础补充,到后续部分会用到,可先跳过该节,到时候反过来看

对于整数a和b, a % b a\%b a%b 的运算方式如下(取余和取模一样):

  • 求整数商: c = [ a / b ] c=[a/b] c=[a/b]
  • 计算模或者余数: r = a − c × b r=a-c\times b r=a−c×b

在整数商中有一个取整操作,取模和取余的不同在于:

运算取整方式
取模求整数商时, 取整向负无穷靠近, 即: − 1 / 3 → − 1 -1/3 \rightarrow -1 −1/3→−1
取余求整数商时, 取整向0靠近, 即: − 1 / 3 → 0 -1/3 \rightarrow 0 −1/3→0

很容易发现, 当 a / b a/b a/b为正数时, 取余和取模的结果是一样的, 只有当其为负数时, 两者才存在区别. 为了方便理解, 下面给出一个例子: 求 − 10 % 3 -10\%3 −10%3 的模和余数.

运算整数商结果
取模-42
取余-3-1

接下来要记住一个结论:

  • C/C++, Java 的%为**取余**
  • Python的%为**取模**

可以看到, 取余运算在a或者b为负数时得到的余数仍为负数, 而取模则能得到正数, 这一点在后续的做题过程中会意识到.

2. 为什么总是对这几个数取模?

按照规律一条条陈述, 结论不言而喻

  • 整数类型(int, 64位操作系统上, 占4个字节)的范围是: − 2 31 ∼ 2 31 − 1 -2^{31}\sim2^{31}-1 −231∼231−1
  • 1e9+7, 1e9+9, 998244353这三个数都小于 2 30 2^{30} 230, 因而对于任意两个模过之后的数 a a a和 b b b:
    • a,b < 2 30 \text{a,b} \lt 2^{30} a,b<230
    • a + b < 2 31 a+b \lt 2^{31} a+b<231
    • a b < 2 60 ab \lt 2^{60} ab<260, 在long long范围内不会溢出
    • 可以使用扩展欧几里德算法

3. 扩展欧几里德算法1:

3.1 欧几里德算法(也叫辗转相除法):

gcd(a, b) = gcd(b, a mod b)

3.2 扩展欧几里德算法:

贝祖定理(也叫裴蜀定理): 给定两个整数a, b, 必定存在整数x、y使得 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b) ⇒ \Rightarrow ⇒ 如果ax+by=1有解,那么gcd(a,b)=1;

扩展欧几里德算法可以用来求模反元素(模逆元)的。

3.2.1 符号约定:

符号含义
g c d ( ⋅ ) gcd(\cdot) gcd(⋅)欧几里德算法
[ ⋅ ] [\cdot] [⋅]向0取整

3.2.2 算法思想:

a x + b y = g c d ( a , b ) = g c d ( b , a % b ) = g c d ( b , a − [ a b ] b ) 取 某 一 x ′ , y ′ 得 : a x + b y = b x ′ + ( a − [ a b ] b ) y ′ = g c d ( a , b ) 故 而 : a ( x − y ′ ) + b ( y − x ′ + [ a b ] y ′ ) = 0 恒 成 立 ⇒ { x = y ′ y = x ′ − [ a b ] y ′ ax+by=gcd(a, b) =gcd(b, a\%b)=gcd(b, a-[\frac{a}{b}]b) \\ 取某一x', y'得:ax+by=bx'+(a-[\frac{a}{b}]b)y'=gcd(a,b) \\ 故而:a(x-y')+b(y-x'+[\frac{a}{b}]y')=0恒成立 \\ \Rightarrow \begin{cases} x = y' \\ y = x' - [\frac{a}{b}]y' \end{cases} ax+by=gcd(a,b)=gcd(b,a%b)=gcd(b,a−[ba​]b)取某一x′,y′得:ax+by=bx′+(a−[ba​]b)y′=gcd(a,b)故而:a(x−y′)+b(y−x′+[ba​]y′)=0恒成立⇒{x=y′y=x′−[ba​]y′​

类似于gcd( ⋅ \cdot ⋅), x’和y’的求法也是递归进行的, gcd( ⋅ \cdot ⋅)的终结条件是: b = 0, 此时:
{ x = y ′ = 1 y = 0 \begin{cases} x = y' = 1 \\ y = 0 \end{cases} {x=y′=1y=0​
得到递归基后, 可以将递归基作为新的x’, y’, 来求上一步的x, y

3.2.3 求模逆元:

对于 a b % n = 1 ab\%n=1 ab%n=1, b称为a的模逆元(反之亦然)

3.2.3.1 费马小定理:

假设p为质数, 那么 a ( p − 1 ) % p = 1 a^{(p-1)} \% p=1 a(p−1)%p=1.

推论: a p − 2 a^{p-2} ap−2为a%p的乘法逆元 ( a × a p − 2 % p = a p − 1 % p = 1 a\times a^{p-2} \% p = a^{p-1} \% p = 1 a×ap−2%p=ap−1%p=1)

3.2.3.2 扩展欧几里德算法: [待完善, 还没完全理清]

a b % p = 1 ⇒ a b % p + k p % p = 1  (kp%p必然为0, 因此最外层不需要加%) 若 g c d ( a , p ) = 1 , 则 : a x + p y = 1 ab\%p = 1 \Rightarrow ab \%p + kp\%p = 1 \text{ (kp\%p必然为0, 因此最外层不需要加\%)} \\ 若gcd(a, p) = 1, 则: ax + py = 1 \\ ab%p=1⇒ab%p+kp%p=1 (kp%p必然为0, 因此最外层不需要加%)若gcd(a,p)=1,则:ax+py=1

参考资料:


  1. https://zhuanlan.zhihu.com/p/58241990 ↩︎

标签:取模,计算机,欧几里德,基础,算法,3.2,ax,gcd
来源: https://blog.csdn.net/fanqiliang630/article/details/121873434

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有