当前位置: 首页 > news >正文

【数论】费马小定理

文章目录

  • 一、同余
    • 1. 同余的定义
    • 2. 同余的性质
  • 二、费马小定理
    • 1. 费马小定理的内容
    • 2. 费马小定理的证明(趣味版)
    • 3. 求解乘法逆元
      • (1) 乘法逆元
      • (2) 费马小定理 + 快速幂求逆元
      • (3) 应用
  • 三、OJ 练习
    • 1. 序列求和 ⭐
      • (1) 解题思路
      • (2) 代码实现
    • 2. 水上舞者索尼娅 ⭐⭐
      • (1) 解题思路
      • (2) 代码实现

一、同余

1. 同余的定义

基本定义:设 m m m 是正整数,如果 a , b a,b ab 的差 a − b a-b ab m m m 整除即 a − b = q m a-b=qm ab=qm,就称 a , b a, \ b a, b 关于模 m m m 同余,或简称同余。记为
a ≡ b ( m o d m ) a\equiv b\pmod m ab(modm)

简单来说就是如果 a a a b b b 除以 m m m 的余数相同,那么 a , b a, \ b a, b 就关于模 m m m 同余。


2. 同余的性质

  • a ≡ b ( m o d m ) a\equiv b\pmod m ab(modm) c ≡ d ( m o d m ) c\equiv d\pmod m cd(modm),则 a ± c ≡ b ± d ( m o d m ) a\pm c\equiv b\pm d\pmod m a±cb±d(modm)

  • a ≡ b ( m o d m ) a\equiv b\pmod m ab(modm) c ≡ d ( m o d m ) c\equiv d\pmod m cd(modm),则 a c ≡ b d ( m o d m ) ac\equiv bd\pmod m acbd(modm)

  • a ≡ b ( m o d m ) a\equiv b\pmod m ab(modm) n ∈ N n\in N nN,则 a n ≡ b n ( m o d m ) a^n\equiv b^n\pmod m anbn(modm)

  • a c ≡ b c ( m o d m ) ac\equiv bc\pmod m acbc(modm) c c c m m m 互质,则 a ≡ b ( m o d m ) a\equiv b\pmod m ab(modm)

  • a ≡ b ( m o d m ) a\equiv b\pmod m ab(modm) ⇔ \Leftrightarrow a − b = k m a-b=km ab=km

可见同余的两侧的数字同时加、减、乘一个数字没有限制,但是同时除以一个数时有一定的限制。


二、费马小定理

1. 费马小定理的内容

费马小定理:如果 p p p 是一个质数,对于任意整数 a a a,都有
a p ≡ a ( m o d p ) a^p\equiv a\pmod p apa(modp)
此外我们还会见到另一种形式:如果 p p p 是一个质数, a a a 不能被 p p p 整除,那么有
a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv1\pmod p ap11(modp)

这是由于同余的性质,如果两边同时除以 a a a 的话,必须要满足 a a a p p p 互质,由于 p p p 是质数,所以等同余 a a a 不能被 p p p 整除。


2. 费马小定理的证明(趣味版)

证明:定理的证明千篇一律,有趣的思维万里挑一。这里我想用一种有趣的方式进行证明,过程如下:

假设现在有一串珠子形成了一个环,环上珠子的数量是 p p p p p p是素数),现在我有 a a a 种颜色,我要给这个环上的每一个珠子进行上色。根据小学知识,每个珠子的上色情况都有 a a a 种,因此总共有 a p a^p ap 种上色方式。

假如我要用至少两种颜色进行上色,总共就有 ( a p − a ) (a^p-a) (apa) 种上色方式。我们现在要证明的是 a p − a ≡ 0 ( m o d p ) a^p-a\equiv0\pmod p apa0(modp),也就是证明 a p − a a^p-a apa 这个式子能够被 p p p 整除,即证明 a p − a = k p a^p-a=kp apa=kp

又回到这个给环上色问题上,问题就可以转化为:如果我们可以把至少用两种颜色这一情况分成 k k k 组,每组都刚好有 p p p 种上色方式
那我们就可以证明 a p − a a^p-a apa p p p k k k 倍了!

在这里插入图片描述

总共 a p a^p ap 种上色方式 { 一种颜色 : a 至少两种颜色: a p − a { p 种 p 种 ⋮ p 种 \begin{cases}一种颜色:a\\\\\\至少两种颜色:a^p-a\begin{cases}p种\\p种\\\vdots \\p种\end{cases}\end{cases} 一种颜色:a至少两种颜色:apa ppp

为了方便,我们把可以通过旋转得到一模一样的两种上色方式称为"同款",如下:

在这里插入图片描述

现在我们把 ”同款“ 的上色方式放在一组里面,由上图不难发现,当我们关注红色的珠子时,当它绕着旋转一圈后,它把每个位置都经过了一边。也就是说,当我们把这个环进行旋转时,它所出现的不同上色方式恰好就是这个环上的珠子的个数,也就是 p p p。也就说明了同款里不同的上色方式就是 p p p。即我们确实可以把 ( a p − a ) (a^p-a) (apa) 种上色方式分成若干个 p p p 种上色方式。

BUT!这好像有个bug啊…万一在旋转过程中出现了两个一模一样的上色咋办?请看VCR:
在这里插入图片描述

别急!这个时候, p p p 是素数的条件就很关键了。既然是素数,就说明它只能被1和它本身整除,所以说实际上是不可能出现像上面那样有几个完整周期排列的。只要不是由几个完整的周期依次排列成环的,就不会出现像上面那样转了不到一圈就完全重合的现象。

综上,我们就说明了在 ( a p − a ) (a^p-a) (apa) 种上色方式中,我们可以把它分成 k k k 组,每组都恰好有 p p p 种上色方式。即
a p − a = k p ⇕ a p − a ≡ 0 ( m o d p ) ⇕ a p ≡ a ( m o d p ) a^p-a=kp\\ \Updownarrow\\ a^p-a\equiv0\pmod p\\ \Updownarrow\\ a^p\equiv a\pmod p\\ apa=kpapa0(modp)apa(modp)
费马小定理,证毕!


3. 求解乘法逆元

(1) 乘法逆元

  • 定义

对于正整数 a a a p p p,若有
a x ≡ 1 ( m o d p ) ax\equiv1\pmod p ax1(modp)
那么把这个同余方程中的 x x x 的解叫做 a a a p p p 的乘法逆元,简称逆元,记作 a − 1 a^{-1} a1

例如 8 x ≡ 1 ( m o d 5 ) 8x \equiv 1 \pmod 5 8x1(mod5) 中, x = 2 , 7 , ⋯ x = 2, 7, \cdots x=2,7, 。那么解出来的这些 x x x 就是 8 8 8 5 5 5 的乘法逆元。

  • a a a 存在乘法逆元的充要条件是 a a a p p p 互质

要想说明 a x ≡ 1 ( m o d p ) ax\equiv1\pmod p ax1(modp) 存在这么一个 x x x ,可以进行一个简单的变形。因为是对 a x ax ax 取模,相当于是把 a x ax ax 减掉了 k k k p p p 最终剩下了 1 1 1,相当于可以写成 a x − k p = 1 ax-kp=1 axkp=1 k k k 是一个整数,这里等价于 a x + p y = 1 ax+py=1 ax+py=1。而根据裴蜀定理,方程 a x + p y = 1 ax+py=1 ax+py=1 有解的充要条件是 gcd ⁡ ( a , p ) = 1 \gcd(a,p)=1 gcd(a,p)=1


(2) 费马小定理 + 快速幂求逆元

a a a 存在乘法逆元的充要条件是 a a a p p p 互质,而**当模数 p p p 是质数时,**满足费马小定理的条件,由费马小定理:
a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv1\pmod p ap11(modp)
提出一个 a a a 出来,可以得到
a ⋅ a p − 2 ≡ 1 ( m o d p ) a\cdot a^{p-2}\equiv1\pmod p aap21(modp)
而这个式子就恰好满足了我们希望的形式,因此可以看出, a a a 的逆元就是 a p − 2 a^{p-2} ap2,而 a p − 2 a^{p - 2} ap2 则可用快速幂进行求解。

注:当 p p p 不是质数的时候,需要使用其他方法进行求解,例如扩展欧几里得算法。

#include <iostream>using namespace std;typedef long long LL;// 必须要保证 a, p 互质,且 p 为质数
LL qpow(LL a, LL b, LL p)
{LL ret = 1;while(b){if(b & 1) ret = ret * a % p;b >>= 1;a = a * a % p;}return ret;
}int main()
{LL x, p; cin >> n >> p;cout << qpow(x, p - 2, p) << endl;  // 打印 x 在模 p 意义下的乘法逆元return 0;
}

时间复杂度与快速幂一致,为 O ( log ⁡ n ) O(\operatorname{log}n) O(logn)


(3) 应用

当我们求解 $(20 \div 3)\bmod 5 $ 这种带模数的运算时,由于 20 ÷ 3 20\div 3 20÷3 是一个小数,我们没法直接求解,这个时候我们可以用逆元把除法变成乘法。这个问题等价于 ( 20 × 3 − 1 ) m o d 5 (20 \times 3^{-1}) \bmod 5 (20×31)mod5,注意这里的 3 − 1 3^{-1} 31 是乘法逆元,不是倒数。 3 3 3 在模 5 5 5 下的逆元是 2 2 2,因此原式等价于 ( 20 × 2 ) m o d 5 = 0 (20 \times 2)\bmod 5 = 0 (20×2)mod5=0


三、OJ 练习

1. 序列求和 ⭐

【题目链接】

序列求和

image-20251011165409008


(1) 解题思路

中学时我们学过, 1 2 + 2 2 + ⋯ + n 2 = n ( n + 1 ) ( 2 n + 1 ) 6 1^2 + 2^2 + \cdots + n^2 = \frac{n(n + 1)(2n + 1)}{6} 12+22++n2=6n(n+1)(2n+1),所以这道题本质上是在求右边这个分式的值然后对 ( 1 0 9 + 7 ) (10^9 + 7) (109+7) 取模的结果。如果我们直接求解,那么我们需要计算 n ( n + 1 ) ( 2 n + 1 ) n(n + 1)(2n + 1) n(n+1)(2n+1),由于 n n n 非常大,所以我们要边乘边取模,但是模完之后的数可能不是 6 6 6 的倍数了,因此我们不能用除以 6 6 6 来运算最终结果,所以需要用乘法逆元把除法转换为乘法。原式等价于求解
n ( n + 1 ) ( 2 n + 1 ) × 6 − 1 m o d ( 1 0 9 + 7 ) n(n + 1)(2n + 1) \times 6^{-1} \bmod (10^9 + 7) n(n+1)(2n+1)×61mod(109+7)
求解 6 6 6 在模 ( 1 0 9 + 7 ) (10^9 + 7) (109+7) 下的逆元采用费马小定理 + 快速幂即可。


(2) 代码实现

#include<iostream>using namespace std;typedef long long LL;const int p = 1e9 + 7;LL n;// 快速幂
LL qpow(LL a, LL n, LL p)
{LL ret = 1;while(n){if(n & 1) ret = ret * a % p;n >>= 1;a = a * a % p;}return ret;
}// 费马小定理求解 x 模 p 下的逆元 
LL rev(LL x, LL p)
{return qpow(x, p - 2, p);
}int main()
{while(cin >> n){// 由于 n 可能非常大,所以每一步乘法运算后都需要取一次模防止溢出LL ans = ((((n % p) * ((n + 1) % p) % p) % p) * ((2 * n + 1) %p)) % p * (rev(6, p)) % p;cout << ans << endl;}return 0;
}

2. 水上舞者索尼娅 ⭐⭐

【题目链接】

P11465 水上舞者索尼娅 - 洛谷

【题目背景】

2024 年 12 月 18 日,《炉石传说》31.2.2 补丁上线,水上舞者索尼娅遭到削弱。现在,在这道题目中,你打开时空之门,回到了水索被削弱前的时候。

【题目描述】

你的场上有 k k k 个【水上舞者索尼娅】,你的手牌中有 1 1 1 张法力值消耗为 1 1 1 的【一串香蕉(还剩 n n n 根)】,你有无尽的法力值,你的手牌数量没有上限。

在你的场上有 k k k 个【水上舞者索尼娅】的情况下:

当你使用 1 1 1 张法力值消耗为 1 1 1 的【一串香蕉(还剩 x x x 根)】时,你将得到:

  • k k k 张法力值消耗为 0 0 0 的【一串香蕉(还剩 x x x 根)】。
  • 1 1 1 张法力值消耗为 1 1 1 的【一串香蕉(还剩 x − 1 x-1 x1 根)】。(若 x = 1 x=1 x=1,则不会得到)

当你使用 1 1 1 张法力值消耗为 0 0 0 的【一串香蕉(还剩 x x x 根)】时,你将得到:

  • 1 1 1 张法力值消耗为 1 1 1 的【一串香蕉(还剩 x − 1 x-1 x1 根)】。(若 x = 1 x=1 x=1,则不会得到)

你一共可以使用多少次【一串香蕉】?

由于答案可能很大,你只需求出答案对 1 0 9 + 7 10^9+7 109+7 取模的余数。

【输入格式】

本题有多组数据

第一行一个正整数 T T T,表示数据组数。

对于每组数据:

一行两个正整数 n , k n,k n,k

【输出格式】

对于每组数据:

输出一行一个整数,表示答案对 1 0 9 + 7 10^9+7 109+7 取模的余数。

【示例一】

输入

3
2 2
3 1
12 34

输出

12
14
178629506

【说明/提示】

1 ≤ T ≤ 1 0 5 1\le T\le10^5 1T105 1 ≤ n , k ≤ 1 0 9 1\le n,k\le10^9 1n,k109

样例解释:

对于第 1 1 1 组数据:

场上有 2 2 2 个【水上舞者索尼娅】,初始手牌中有 1 1 1 张法力值消耗为 1 1 1 的【一串香蕉(还剩 2 2 2 根)】。

使用: 1 1 1 张法力值消耗为 1 1 1 的【一串香蕉(还剩 2 2 2 根)】。
手牌:

  • 2 2 2 张法力值消耗为 0 0 0 的【一串香蕉(还剩 2 2 2 根)】。
  • 1 1 1 张法力值消耗为 1 1 1 的【一串香蕉(还剩 1 1 1 根)】。

使用: 2 2 2 张法力值消耗为 0 0 0 的【一串香蕉(还剩 2 2 2 根)】。
手牌:

  • 3 3 3 张法力值消耗为 1 1 1 的【一串香蕉(还剩 1 1 1 根)】。

使用: 3 3 3 张法力值消耗为 1 1 1 的【一串香蕉(还剩 1 1 1 根)】。
手牌:

  • 6 6 6 张法力值消耗为 0 0 0 的【一串香蕉(还剩 1 1 1 根)】。

使用: 6 6 6 张法力值消耗为 0 0 0 的【一串香蕉(还剩 1 1 1 根)】。
手牌:

共使用 1 + 2 + 3 + 6 = 12 1+2+3+6=12 1+2+3+6=12 张【一串香蕉】。


(1) 解题思路

我们把法力值消耗为 1 1 1 的【一串香蕉(还剩 n n n 根)】记为 ( 1 , n ) (1, n) (1,n),以及场上有 k k k 个【水上舞者索尼娅】。此时我们使用一次一串香蕉,根据题意,你会得到 k k k ( 0 , n ) (0, n) (0,n) 和 一个 ( 1 , n − 1 ) (1, n - 1) (1,n1),此时再把 k k k ( 0 , n ) (0, n) (0,n) 全部使用,那么就会得到 k k k ( 1 , n − 1 ) (1, n - 1) (1,n1),这个时候,你会得到 k + 1 k + 1 k+1 ( 1 , n − 1 ) (1, n - 1) (1,n1)

(1, n) --使用k+1次--> (k + 1)个(1, n - 1)

那么以此类推,我们可以得出以下规律

(1, n) --使用k+1次--> (k + 1)个(1, n - 1) --使用(k+1)^2次--> (k + 1)^2个(1, n - 2)  ... 

所以我们最终就可以使用 ( k + 1 ) + ( k + 1 ) 2 + ⋯ + ( k + 1 ) n = ∑ i = 1 n ( k + 1 ) i (k + 1) + (k + 1)^2 + \cdots + (k + 1)^n = \sum\limits_{i = 1}^{n}(k + 1)^i (k+1)+(k+1)2++(k+1)n=i=1n(k+1)i 张【一根香蕉】。

根据等比数列求和公式再进行整理,最终答案就是 ( k + 1 ) n + 1 − k − 1 k m o d ( 1 0 9 + 7 ) \frac{(k+1)^{n + 1} - k - 1}{k} \bmod (10^9 + 7) k(k+1)n+1k1mod(109+7)。由于在模运算中出现了除法,所以等价于求解 [ ( k + 1 ) n + 1 − k − 1 ] × k − 1 m o d ( 1 0 9 + 7 ) [(k+1)^{n + 1} - k - 1]\times k^{-1} \bmod (10^9 + 7) [(k+1)n+1k1]×k1mod(109+7)


(2) 代码实现

#include<iostream>using namespace std;typedef long long LL;const int p = 1e9 + 7;
LL n, k;// 快速幂
LL qpow(LL a, LL n, LL p)
{LL ret = 1;while(n){if(n & 1) ret = ret * a % p;n >>= 1;a = a * a % p;}return ret;
}// 求解 x 模 p 下的逆元 
LL inv(LL x, LL p)
{return qpow(x, p - 2, p);
}int main()
{int t;cin >> t;while(t--){cin >> n >> k;LL ans = (qpow(k + 1, n + 1, p) - k - 1) * inv(k, p);// 注意把答案补成最小非负整数cout << ((ans % p) + p) % p << endl;}
}

http://www.dtcms.com/a/524865.html

相关文章:

  • goland23.1自带dlv版本太低,使用新版dlv
  • 做外贸出口的网站企业免费做网站
  • Kotlin × Gson:为什么遍历 JsonObject 要用 entrySet()
  • 中国建设安全监理协会网站年轻的儿媳
  • 网站网站到底怎么做个人代运营一般怎么收费
  • segformer算法——Mix-FFN详细讲解
  • 高精度算法全解析:从原理到实现
  • 参考线模块(上)
  • 鸿蒙Next图片开发指南:从解码、处理到接收的完整实践
  • 2025年第六届MathorCup大数据竞赛B题超详细解题思路
  • How to Write Hotkeys(如何编写热键)
  • 基于python语音信号的抑郁症识别模型设计与应用
  • 基于python语音信号的呼吸道疾病诊断模型设计
  • 西城网站建设余姚电商交易网站建设
  • 【交换机工作原理深度解析:从基础架构到前沿技术】
  • 学校培训网站建设网页设计师培训无锡
  • 「用Python来学微积分」12. 无穷小量和无穷大量
  • Elasticsearch从入门到进阶——搜索优化原理
  • 农田、果园与灌区气象监测的技术应用与实践价值
  • php做网站好吗wordpress博客非插件
  • 继承(2),咕咕咕!
  • C++编程技巧和规范_9_引用计数解析
  • android11禁止安装apk
  • 深入了解linux网络—— 自定义协议(下)
  • 金麦建站官网成都视频剪辑培训
  • 【C++闯关笔记】详解多态
  • 数据库技术指南(二):MySQL CURD 与高级查询实战
  • 用mvc做网站报告做做做网站
  • 设置一个自定义名称的密钥,用于 git 仓库上下传使用
  • MAC Flood与ARP Flood攻击区别详解