最大公约数性质:
- 定理:如果a,b是不全为0的任意整数,则gcd(a, b)是a与b的线性组合{ax+by:x,y∈Z}中的最小正元素。
- 推论1:对于任意整数a,b,如果d|a并且d|b,则d|gcd(a, b)。
- 推论2:对于所有整数a和b以及任意非负整数n,gcd(an, bn)=n*gcd(a,b)。
- 推论3:对所有正整数n,a和b,如果n|ab并且gcd(a, n)=1,则n|b。
欧几里得算法求最大公约数:
int gcd(int a, int b)
{
return b==0?a:gcd(b, a%b);
}
扩展欧几里得算法:
1.(求二元一次方程 ax+by=c 的整数解)若c mod gcd(a, b) == 0, 则该方程存在整数解,否则不存在整数解- 定理:对于不完全为0的非负整数a,b,gcd(a,b)表示a,b的最大公约数d,必然存在整数对x,y,使得gcd(a,b)=d=ax+by
对于gcd(a,b) = d,对(a, b)用欧几里德辗转相除会最终得到(d, 0)。此时对于把a =d, b = 0 代入a*x + b*y = d,显然x = 1,y可以为任意值。
gcd = d = b*x + (a%b)*y
gcd = d = b*x + (a - [a/b]*b)*y)
gcd = d = a*y0 + b*(x0 - [a/b]*y0)由上式子可以推出 a*x + b*y = d的解为x = y0, y = x0 - [a/b]*y0;
代码:
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1,y=0;
return a;
}
int ret=exgcd(b,a%b,x,y);
int tmp=x;
x=y;
y=tmp-a/b*y;
return ret;
}
- ( 求模线性方程 ax ≡ b(mod n)的解 ),假设对整数x, y,有gcd(a, n) = ax’ + ny’ ,则方程 ax≡ b ( mod n )有一个解的值为x0.
- 满足:x0 = x’ * (b/d) mod n.
ax0 ≡ ax’(b/d) (mod n)
≡ d(b/d) (mod n)
≡ b (mod n) - 代码:
- 满足:x0 = x’ * (b/d) mod n.
Modular_Linear
int Modular_Linear(int a, int b, int n)
{
//ax = b (mod n)
int d, x, y, x0, i;
d = Extend_Euclid(a, n, x, y);
if(b%d == 0)
{
x0 = x * (b/d) % n + n;//x0为任意一个解
for(i = 0;i < d;i ++)
cout << (x0 + i*n/d) % n <<endl;//方程由d个解
}
return 0;
}
- 最小公倍数:
LCM(a, b) = a / GCD(a, b) × b
//先除后乘 防止数字过大爆炸