擴展歐幾里得算法:
求出滿足條件唯一的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;
}