同余&逆元&CRT学习笔记
前记
upd 2022/10/9 14:36:06 : 修改了一些错误。
upd 2022/10/17 19:36:54 : 修改了 Latex 格式。
第一篇学习笔记
之前搞了好几天,后来发现忘得差不多了,又重新温习,顺便做个笔记;涉及众多式子,如果有错请指出
| 目录: |
|---|
| 1.同余式 |
| 2.裴蜀定理 |
| 3.欧几里得&扩展欧几里得 |
| 4.(乘法)逆元 |
| 5.求(乘法)逆元 |
| 6.中国剩余定理(CRT) |
1.同余式
如果两个数
同余式就是如上这个式子,如果换成比较简单的形式就是
同时他还有个基本性质
显然的,若
这里
同余关系还具有
自反性:
对称性:
传递性:
这些性质都可以根据变形后的式子轻易得出。
2.裴蜀定理
2.1裴蜀定理
在了解了同余式的定义后,我们来看一个与之相关的定理
裴蜀定理得名于法国数学家艾蒂安·裴蜀,亦称贝祖定理。
1.裴蜀定理是指方程
2.同时,一定存在整数
3.特别的,只有
极不严谨的证明:
方程两边同时除以
因为
通俗来说就是方程左边一定为整数,所以方程右边也一定为整数,所以
更严谨的证明方法请 bdfs。
2.2 同余式与裴蜀定理的关系
那么为什么说同余式与裴蜀定理有关呢,因为
由于我们要求的方程是与
对于这个方程我们便可用扩展欧几里得来求解
3.欧几里得&扩展欧几里得
3.1 欧几里得算法
我们自然是要先来看看欧几里得算法的
古希腊数学家欧几里得在其著作《The Elements》中最早描述了这种算法,所以被命名为欧几里得算法。
欧几里得算法又称辗转相除法,一般用来求两个数的最大公约数,即
证明:
假设
设
则
则
我们知道
因此
int gcd(int a,int b){return (b)?gcd(b,a%b):a;}#include<algorithm>
using namespace std;
int a,b;
int main(){int c=__gcd(a,b);}3.2 扩展欧几里得


扩展欧几里得算法是欧几里得算法的扩展(废话),即我们在辗转相除的过程中,求出
具体的来说我们在进行辗转相除时
设当前的两个数为
则下一轮要递归时的两个数为
假设我们已经求出了
因为
整理得
所以
那么我们的边界条件呢?
我们在辗转相除时最后当
也就是说相当于
所以初始时
设求出来的特解为
另外,扩展欧几里得还可以用来求逆元
//用来求不定方程 ax+by=c 的解
int x,y;
int exgcd(int a,int b,int &x,int &y)
{
if(!b){x=1,y=0;return a;}
int d=exgcd(b,a%b,y,x);
y-=(a/b)*x;return d;
}| 例题: |
|---|
| P1082 [NOIP2012 提高组] 同余方程 |
| P1516 青蛙的约会 |
4.逆元
在数论中,如果
实际意义即如果要在模
通常使用扩展欧几里得,费马小定理,和线性递推法来求乘法逆元
5.求逆元
5.1 扩展欧几里得法
我们设
就相当于求
利用扩展欧几里得法求解即可
//用来求a在%p意义下的乘法逆元x
int x,y,a,p;
void exgcd(int a,int b,int &x,int &y)
{
if(!b){x=1,y=0;return ;}
exgcd(b,a%b,y,x),y-=(a/b)*x;return ;
}
int main()
{
exgcd(a,p,x,y);
x=(x%p+p)%p;
}5.2 费马小定理
皮埃尔·德·费马于1636年发现了这个定理。在一封1640年10月18日的信中他第一次使用了上面的书写方式。在他的信中费马还提出a是一个素数的要求,但是这个要求实际上是不必要的。
费马小定理为:若
至于证明,我不会
从逆元的定义推导,可得
利用快速幂计算
//仅适用于p为质数
int a,b,p,ans=1;
int main()
{
b=p-2;
while(b)
{
if(b&1) ans=ans*a%p;
a=a*a%p;
b>>=1;
}
}5.3 线性递推法
同时求逆元还用一种线性递推法
证明:
设
在模
整理得
则
即
//仅适用于p是质数
ans[1]=1;
for(int i=2;i<=n;i++)
{
ans[i]=(-p/i*ans[p%i]);
ans[i]=(ans[i]%p+p)%p;
}| 例题 |
|---|
| P3811 【模板】乘法逆元 |
6.中国剩余定理(CRT)
最后一趴
孙子定理是中国古代求解一次同余式组的方法。是数论中一个重要定理。又称中国余数定理。一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题。
我们知道了如何(扩展欧几里得)求一元线性同余方程
但如果是一元线性同余方程"组"呢?
总不能求出每一个然后找公共部分吧
中国剩余定理即解决此类问题的方法
一元线性同余方程组即:
如果我们将每个方程分开看,即:
如果已经满足了
同理当
设有
题目上一般会给出模数两两互质的条件,继而可得当
由于模数两两互质,所以
此时求
解得
特解即为:
通解即为模
综上得方程组的解为(这里的逆元为模
for(int i=1;i<=n;i++) cin>>a[i]>>b[i],x*=a[i];
for(int i=1;i<=n;i++)
{
int r=x/a[i];
ans+=(b[i]*r*inv(r,a[i]))%x;
}| 例题: |
|---|
| P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪 |
| P3868 [TJOI2009] 猜数字 |
参考资料:
date:2022/10/5
