您的位置:首页 > 其它

扩展欧几里得 模板(转)

2018-02-14 10:30 330 查看
转自http://blog.yueling.me

扩展欧几里得模板。
求解两个元是整数的方程可以转换为取余消元枚举其中一个数,这是另一种思路。
复杂度和gcd一样是lg(n)。
gcd(a,b)//a,b可以是任意整数,但是为了保证结果是正的,所以让a,b取绝对值. 显然gcd(a,b) == gcd(|a|,|b|)
long long e_gcd(long long a, long long b, long long& x, long long& y){
if(b == 0){
x = 1;
y = 0;
return a;
}
long long ans = e_gcd(b, a%b, y, x);
y -= x*(a/b);

return ans;
}


1
2
3
4
5
6
7
8
9
10
11
推导思路: 

当最底层时,gcd(a,0)==a==a*1+b*0; 

又因为公因数相等,所以可以找到上一步的一个式子联立,找到递推关系.
应用: 

1.求解不定方程。 

2.求解模的逆元。 

3.求解同余方程。 

以上三个换汤不换药。
设: ax+by=c 

当且仅当c%gcd(a,b) == 0时才有整数解。 

x,y可能为负数。
通解: 

X = x + b/gcd(a,b)*t //t可以是负数 

Y = y - a/gcd(a,b)*t //利用最小公倍数保证求出的解时最小的。
最小解:令 m = | b/gcd(a,b) |; 

( (x % m) + m) % m;//保证结果是正数 

也可以当x为负的时候再加一个m来保证结果是正数。
如果c != gcd(a,b), 那么先利用e_gcd函数得到原方程的特解:x0*c/gcd(a,b),再通过( (x % m) + m) % m得到最小正整数解。
为什么要先得到特解再找最小正整数解? 

令m == b/ gcd(a,b) 

n == a/ gcd(a,b) 

显然am == bn 

假设c/gcd(a,b) == 2: 

如果不是先得到特解,而是先找最小正整数解最后再乘以2, 

则: 

2*x0*a + 2*y0*b = c 

当x0增加m时: 

2*x0*a+2ma + 2*y0*b-2bn = c 

此时我们就发现2*x0*a+ma + 2*y0*b-bn = c这个式子也成立,但是永远都取不到了。 

如果先取特解再找最小正整数解,则每次变动单位为ma都可以取得到。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: