同余相关
取余定义:
整除
表示 能被 整除,即 。
同余
表示 。
相当于 。
裴蜀定理
内容
若 , 是整数,且 ,那么对于任意的整数 , , 都一定是 的倍数,特别地,一定存在整数 ,使 成立。
同余方程
欧几里得算法
int gcd(int x,int y)
{
if(!y) return x;
return gcd(y,x%y);
}
扩展欧几里得
可以通过欧几里得求 gcd 的过程求解 。
设 ,当前的式子为 ,则下一轮要递归的式子为 。
假设我们已经得出了 ,需要求出 。
由 可得
整理得
边界:辗转相除最后 返回 。
所以当 时,我们令 即可( 可以为任意数,因为 )。
求出了特解,我们就可以推出通解。
设通解为 ,
其实可以先求出来 在将 带入进原式得出 。
设一个同余方程为 ,。
由裴蜀定理可知, 一定为 的倍数。
所以可以先求出 的解。再求出 解。
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,x,y);
int t=x;
x=y;y=t-a/b*y;
return d;
}
逆元
若 , 互质,则称 为 的逆元。( )其实就是 在模意义下的倒数。
扩展欧几里得求逆元
设 为 模 意义下的逆元,由逆元定义的可得
使用扩展欧几里得即可
int x,y;
void exgcd(int a,int p,int &x,int &y)
{
if(!b) {x=1,y=0;return ;}
exgcd(p,a%p,x,y);
int t=x;
x=y;y=t-a/p*y;
return ;
}
int main(){
a=read(),p=read();
exgcd(a,p,x,y)
printf("%lld",(x%p+p)%p);//( x 一直加 p 直到大于 0 )
}
费马小定理求逆元
费马小定理为:如果 是一个质数,而整数 不是 的倍数,则有 。
由逆元的定义可以得出
用快速幂计算即可
inline int qpow(int a,int p){
int b=p-2;int base=a,ans=1;
while(b){
if(b&1) ans=(ans*base)%p;
base=(base*base)%p;
b>>=1;
}
return ans;
}
线性递推法
设 ,则 。
可得递推式:
int inv[M];
inline void getInv(int n,int p)
{
inv[1]=1;
for(int i = 2;i <= n;i++){
inv[i]=-p/i*inv[p%i];
inv[i]=(inv[i]%p+p)%p;
}
}
中国剩余定理(CRT)
出自《孙子算经》
有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?
本质是求解一个同余方程组
有一个限制: 两两互质。
我们可以将方程组分开来看:
只有当 时,
使 ,我们设 ,解下面的同余方程:
因为 两两互质,可以用 exgcd 求解,即求关于 的同余方程:
(相当于求 的在模 意义下的逆元 )
将解代回得
再将 代回得
解即为
for(int i = 1;i <= n;i++)
a[i]=read(),b[i]=read(),P*=a[i];
for(int i = 1;i <= n;i++)
{
int M=P/a[i];
ans+=(b[i]*M*inv(M,a[i]))%P;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步