模运算是一个高深的地方,初来乍到,还是写一下为敬QAQ。。。
记号
我们把 除以 所得的余数记作 。
如果 ,即 , 除以 所得的余数相等,那么我们记作:
基本性质
模运算有一些基本性质:如果 且有 ,那么下面的模运算律成立:
这就是我们平常经常利用的性质,如果答案对一个数取模,那么模了再加,乘,减都是不影响答案的。特别注意除法是没有这个性质的!
剩余系
如果一个剩余系中包含了这个正整数 所有可能的余数(一般地,对于任意正整数 ,有 个余数:),那么就被称为是模 的一个完全剩余系,记作 ;而简化剩余系就是完全剩余系中与 互素的数的那些元素,记作
里面的每一个元素代表所有模 意义下与它同余的整数。例如 时, 的元素 实际上代表了 这些模 余 的数。 我们把满足同余关系的所有整数看作一个同余等价类。
自然地,在 中的加法,减法,乘法,结果全部要在模 意义下面了,例如在 中,。
逆元
在实数运算下面,如果 ,那么可以说 互为倒数,它们相乘永远得 。不幸的是, 的运算下面也有倒数的概念,而且要恐怖的多。
如果在 中两元素 满足 ,比如在 中,,那么我们就说 互为模 意义下乘法的逆 !记作 。
我们知道,除以一个数等价于乘以这个数的倒数,在模运算中,除以一个数等于乘上这个数的逆(如果这个数存在乘法逆的话)!举个栗子,在 中, 。
看上去有点神乎其神, 甚至不是整数,怎么可能答案是 ???别忘了,剩余系中每一个元素都对应一个同余等价类,所以 的实际含义是:“假定有两个整数 满足 是整数且 除以 的余数分别是 和 ,那么 除以 的余数等于 ” ,比如 时就成立。
线性模方程
线性模方程是下面这玩意,其中 是未知数,我们需要做的事情是求出 的 的解集。
因为同余,所以有 ,即 ,这个方程有解当且仅当 。这是第一步。
假设 的逆在模 意义下存在,为 ,那么根据基本性质,两边可以同乘 ,则得到 ,是不是这样,问题就轻松解决了呢?并不是, 的逆极有可能在模 意义下不存在,我们试着求一下在模 意义下 的逆。即解
转化
移项
根据扩展欧几里得算法,当且仅当 ,模 意义下 的逆存在。所以,我们要解 ,必须将其转化,使得 的乘法逆存在。
将 两边同时除以 ,得到:
于是问题回到了求解:
这一回,我们能保证 ,所以 在这里一定有乘法逆!
那么这个方程的解是在 剩余系内的:
但是我们需要求解的是 剩余系内的元素,怎么转换过去呢?设 ,那么我们有无穷多个实数解: 。我们想要知道,这无穷多个实数解,在模 意义下究竟有多少个等价类(即模 会有多少个不同的余数)?大家可能已经发现了,正好 个,分别为 。
为什么呢?假设 与 模 同余,那么 ,必定是 的倍数,也就是 是 的倍数。所以是 个一轮回的!
这些数模 同余;
这些数模 同余;
...
这些数模 mm 同余;
而 之间不可能同余,因为不满足 是 的倍数。所以,方程 要么无解,要么恰有 个解。
总结起来,解线性同余方程只需要求 的乘法逆,但分析过程还是有些恼人的。
中国剩余定理
更加详细的介绍:Here
现在如果有多个同余方程,即同余方程组,变量只有一个,且 前面系数为 , 任意 之间互素,该怎么做呢?
中国剩余定理在这里派上用场了,它并不是一种算法,而是一种思考、构造的方法。
现在有方程组 。我们令 。那么解一定可以表示为 剩余系中的一个元素,即 。我们来构造这个解。
由于 之间互素,可以得到 ,构造出这样一个方程 ,由于 ,此方程一定有解。用扩展欧几里得算法解出 ,令 ,现在有一些有趣的性质,方程两边都模 ,得到 即 。
依据这一性质,我们构造得到方程在 剩余系中的唯一解 。验证一下,只需把每个方程带进去,看是否都成立即可。对于 ,将得到的解右边模 ,惊奇的发现,除了 这一项的结果为 之外,其余项的结果都是 。
原因是 一模变成 ,还有 中 必定含有因子 ,所以一模就成 了。
则对于每一个 ,我们都能得到一个与原方程组一模一样的同余等式,所以这个解是正确的。
所以 显然是一个实数解, 都是解,原方程组有无穷组实数解。
欧拉定理
在数论中,欧拉定理是一个关于同余的性质。欧拉定理表明,若 为正整数,且 互素,则:
特别的,当 为素数的时候,aa 可取任意 内元素。由于 ,故有:
这就是费马小定理。观察到右边 的存在,发现与之前所说的逆元有一点相似:
是逆元,根据费马小定理,有 ,故可以快速幂在 的时间内快速求出任意 内元素的逆元,但只有在 是素数的时候才起作用。
离散对数
当 为素数的时候,解模方程:
如果是实数范围内,答案是 ,可惜并不是,这里采用一种精妙的解决办法。
解:根据欧拉定理有:,又 ,所以 在模 剩余系内的值无限循环,以 为循环节。
所以,只需检查 时是不是解即可。但这样复杂度是 的,下面用一种构造手段将复杂度降下来:
我们先检查前 项( 取值稍后说明),即 模 的值是否为 ,并把 的值保存在 中,求出 逆 。
下面接着考虑 ,这次不需要检查,如果他们当中存在解,说明存在 使得 。两边乘 ,得到 ,也就是说我们只需要检查有没有一个 ,使得 ,这相当于依次检查了 。
如果仍然没有检查到解,这回考虑 ,同样的,我们只需要检查有没有一个 ,使得 ,这相当于依次检查了 。
显然使用 STL 中的 MAP 可以帮我们快速完成检测操作。预处理出 的复杂度是 ,求出 的复杂度是 ,一共有 轮检测,每轮复杂度 。总复杂度 ,当 时,复杂度最低为:
指数循环节
当 大到一定程度的时候,我们没有办法算 了,这时需要用到指数循环节。
如果 ,由欧拉定理 可知指数以 为循环节不断循环,故有
如果 ,似乎不好做了,不过也有公式!
需要声明一下,只有 时此公式成立,所以千万不要盲目的取余了再加!
关于 的公式参考:Here
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 分享4款.NET开源、免费、实用的商城系统
· 解决跨域问题的这6种方案,真香!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库
· 5. Nginx 负载均衡配置案例(附有详细截图说明++)
2020-07-30 (转)Github+jsDelivr+PicGo 打造稳定快速、高效免费图床
2020-07-30 解决Github中使用Octotree时,出现 Error: API limit exceeded 报错 或者 Error: Connection error报错的问题(详细操作)
2020-07-30 P3372 【模板】线段树 1
2020-07-30 【题解】Qin Shi Huang's National Road System HDU - 4081 ⭐⭐⭐⭐ 【次小生成树】