翻了好久的博客终于找到了一篇我能看懂的博客。。。。。。。可能是因为我太笨了,大牛们写的我都无法理解。。。。。。
下面开始进入正题。
假设有两个方程:
ax + by = gcd(a,b);
bx’ + (a%b)y’ = gcd(b,a%b);
由欧几里德可知gcd(a,b) = gcd(b,a%b)
那么 ax + by = bx’ + (a%b)y’
= bx’ + [a - (a/b)*b]*y’//之前对于取模之停留在取余数,不知道a%b=a - (a/b)*b
= ay’ + b[x’ - (a/b)*y]
那么就有恒等关系 x = y’; y = x’ - (a/b)*y’
求解不定方程 ax + by = c :
令 d = gcd(a,b)
则 (a/d)*x + (b/d)*y = c/d , 那么原不定方程有有解的条件就是 c 是 gcd(a,b) 的倍数
如果有解那么 令 k = c/d 则 k*(ax0 + by0) = k*d ,即 (a/d)*x0 + (b/d*y0) = 1
设(x0,y0) 是 (a/d)*x0 + (b/d*y0) = 1 的一组解,则x = (c/d)*x0; y=(c/d)*y0;
(x,y)是 ax + by = c 的一组解。
不定方程的通解:
若(x0,y0)是不定整数方程ax+by = c的一组解,则他的任意整数解都可以表示成
(x0 + kb’, y0 - ka’),其中a’ = a/gcd(a,b), b’ = b/gcd(a,b).
A/B:
设有 (A/B)%P = k (P为素数) , 则 A/B = k + P*x , 因此 A = k*B + P*B*x。
设 A%P = n ,则 n = k*B%P 即, k*B = n + P*y
则 (k/n)*B + (-y/n)*P = 1 = gcd(B,P)
逆元?
突然冒出来的逆元。。。。。。。
直接上公式吧!
欧拉定理: aφ(n) = 1(mod n)(gcd(a,n) = 1)
费马小定理: ap-1 = 1(mod p)(gcd(a,p)=1) (p为素数)
有没有发现什么? 是的这就是同一个式子。
对于欧拉函数当且仅当 n 为素数时φ(n)=n-1 。
扩展欧几里得 与 逆元:
设ax +py = 1(p为素数。是不是很眼熟,没错和A/B里面的是同一个式子)
下面来波骚操作, ax % p + py % p = 1 % p
则 ax % p = 1 % p 即 ax = 1(mod p)
最后贴上我的垃圾代码:
#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
ll extgcd(ll a,ll b,ll &x, ll &y) // 求解 ax + by = 1
{
ll res=0;
if (!b) res=a,x=1,y=0;
else res=extgcd(b,a%b,y,x),y-=(a/b)*x;
return res; //返回a与b的最大公约数
} //x,y为ax+by=1的一组可行解
void Indefinite_equation(ll a,ll b,ll c) // 求解 ax + by = c
{
ll x,y;
ll d=extgcd(a,b,x,y);
ll k=c/d;
if (c%d){printf("No solution\n"); return;}
x=k*x;
//x=x+t*(k*b/d); 通解
y=(c-a*x)/b;
printf("x=%lld; y=%lld;\n",x,y);
}
int main()
{
ll a,b,c;
scanf("%lld%lld%lld",&a,&b,&c);
Indefinite_equation(a,b,c);
return 0;
}