扩展欧几里得算法:
求出满足条件唯一的x,y的值
其中 就是最大公约数,因为可由和,且
故可表示为和的线性组合
同理也可向上表示。这样得到最大公约数之后,一直向上回溯即可找到满足条件的x,y
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll ExGcd(ll a,ll b,ll &x,ll &y)//求 a b 最大公约数,且得到gcd(a,b)=x*a+y*b;
{
if(!b)
{
x=1;
y=0;
return a;
}
ll gcd=ExGcd(b,a%b,x,y);
ll temp,k;
k=a/b;
temp=x;
x=y;
y=temp-k*y;
return gcd;
}
利用扩展欧几里得求一次同余方程
形如式子,求满足条件的x。
- 且只有满足 的时候才有解。
令,
那么等式①两边同乘以即可得到
即(为的扩展欧几里得公式中a的系数)
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll ExGcd(ll a,ll b,ll &x,ll &y)//求 a b 最大公约数,且得到gcd(a,b)=x*a+y*b;
{
if(!b)
{
x=1;
y=0;
return a;
}
ll gcd=ExGcd(b,a%b,x,y);
ll temp,k=a/b;
temp=x;
x=y;
y=temp-k*y;
return gcd;
}
bool IsOk;
ll calc(ll a,ll c,ll m)
{
ll x,y;
ll gcd=ExGcd(a,m,x,y);
if(c%gcd!=0)
{
IsOk=false;
return 0ll;
}
return c/gcd*x%m;
}
利用费马小定理求逆元
补充一个 欧拉定理:
设φ(x)的x的欧拉函数值,如果有a和p互素,则有
- 费马小定理条件:a,p互素,且p是素数
则:
即: 关于 的逆元为
/*
快速幂取模即可
*/
利用扩展欧几里得求逆元
前提
gcd(a,q)==1
逆元即ax+qy=1 (mod q)中的x
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
ll ExGcd(ll a,ll b,ll &x,ll &y)//求 a b 最大公约数,且得到gcd(a,b)=x*a+y*b;
{
if(!b)
{
x=1;
y=0;
return a;
}
ll gcd=ExGcd(b,a%b,x,y);
ll temp,k;
k=a/b;
temp=x;
x=y;
y=temp-k*y;
return gcd;
}
ll getinv(ll a,ll m)
{
ll x,y;
if(ExGcd(a,m,x,y)!=1)
return -1;//不互质 不存在逆元
return x;
}