欧几里得和拓展欧几里得模板

参考:http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html

 1 /*
 2 gcd求最大公约数,两数相乘在除gcd可以求最小公倍数
 3 */
 4 int gcd(int a, int b)
 5 {
 6     return b ? gcd(b, a % b) : a;
 7 }
 8 
 9 /*
10 exgcd
11 
12 学习网址:http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html
13 
14 扩展欧几里德算法的应用主要有以下三方面:
15 (1)求解不定方程; 找出一对整数(x, y), 使得 a*x + b*y = gcd(a, b).
16 (2)求解模线性方程(线性同余方程);
17 (3)求解模的逆元;
18 
19 结论1:若方程 ax + by = c 的一组整数解为(x0, y0),
20 则它的任意整数解都可以写成(x0 + k * b', y0 + k * a'),其中 a' = a / gcd(a, b), b' = b / gcd(a, b), k 为任意整数.
21 
22 结论2:设a, b, c为任意整数, g = gcd(a, b), 方程 a*x + b*y = g 的一组解是(x0, y0), 则当 c 是 g 的倍数时
23 a*x + b*y = c 的一组解是(x0*c/g, y0*c/g);当 c 不是 g 的倍数时无整数解.
24 */
25 int exgcd(int a, int b, int &x, int &y)
26 {
27     if(b == 0) {
28         x = 1;
29         y = 0;
30         return a;
31     }
32     int r = exgcd(b, a % b, x, y);
33     int t = x;
34     x = y;
35     y = t - a / b * y;
36     return r;
37 }
38 
39 /*
40 (1) : 解不定方程 a * x + b * y = c
41 */
42 bool linear_equation(int a, int b, int c, int &x, int &y)
43 {
44     int d = exgcd(a, b, x, y);
45     if(c % d) { //没有整数解
46         return false;
47     }
48     int k = c / d;
49     x = x * k, y = y * k; //求得的是其中一组解
50     return true;
51 }
52 
53 /*
54 (2) : 求解模线性方程的解集 : a * x ≡ b (mod n)
55       可以写成:a * x + n * y = b
56 */
57 bool modular_linear_equation(int a,int b,int n)
58 {
59     int x, y, x0, div;
60     int d = exgcd(a, n, x, y); //解集共有d个数
61     if(b % d) {
62         return false;
63     }
64     x0 = x * (b / d) % n; //最小整数解
65     div = n / d;
66     if(div < 0) div = -div;
67     //每一个解的间隔是 n/d ,共有 d 个解
68     //如果有负数要变成正数
69     /*
70     求最小整数解: ans = x0 % div;
71                  if(ans <= 0) ans += div;
72            
73            就是: ans = (x0 % div + div) % div;
74                  return ans;
75     */
76     for(int i = 1; i <= d; i++) {
77         printf("%d
", (x0 + i * div) % n);
78     }
79     return true;
80 }
81 
82 /*
83 (3) : 求解模的逆元:形如 a * x ≡ b (mod n) 的方程,如果gcd(a, n) == 1, 则方程只有唯一解
84 在这种情况下,如果b == 1,同余方程就是 a * x ≡ 1 (mod n), gcd(a, n) = 1
85 这时求出的 x 为 a 的对模 n 乘法的逆元
86 用拓展欧几里得可以求出 x
87 */
原文地址:https://www.cnblogs.com/fightfordream/p/5767436.html