Function extgcd_recurse

Source
pub fn extgcd_recurse(a: i64, b: i64) -> (i64, i64, i64)
Examples found in repository?
crates/competitive/src/math/gcd.rs (line 44)
40pub fn extgcd_recurse(a: i64, b: i64) -> (i64, i64, i64) {
41    if b == 0 {
42        (a, 1, 0)
43    } else {
44        let (g, x, y) = extgcd_recurse(b, a % b);
45        (g, y, x - (a / b) * y)
46    }
47}
48
49#[codesnip::entry]
50pub fn extgcd(mut a: i64, mut b: i64) -> (i64, i64, i64) {
51    let (mut u, mut v, mut x, mut y) = (1, 0, 0, 1);
52    while a != 0 {
53        let k = b / a;
54        x -= k * u;
55        y -= k * v;
56        b -= k * a;
57        std::mem::swap(&mut x, &mut u);
58        std::mem::swap(&mut y, &mut v);
59        std::mem::swap(&mut b, &mut a);
60    }
61    (b, x, y)
62}
63
64pub fn extgcd_binary(mut a: i64, mut b: i64) -> (i64, i64, i64) {
65    if b == 0 {
66        return (a, 1, 0);
67    } else if a == 0 {
68        return (b, 1, 0);
69    }
70    let k = (a | b).trailing_zeros();
71    a >>= k;
72    b >>= k;
73    let (c, d) = (a, b);
74    let (mut u, mut v, mut s, mut t) = (1, 0, 0, 1);
75    while a & 1 == 0 {
76        a /= 2;
77        if u & 1 == 1 || v & 1 == 1 {
78            u += d;
79            v -= c;
80        }
81        u /= 2;
82        v /= 2;
83    }
84    while a != b {
85        if b & 1 == 0 {
86            b /= 2;
87            if s & 1 == 1 || t & 1 == 1 {
88                s += d;
89                t -= c;
90            }
91            s /= 2;
92            t /= 2;
93        } else if b < a {
94            std::mem::swap(&mut a, &mut b);
95            std::mem::swap(&mut u, &mut s);
96            std::mem::swap(&mut v, &mut t);
97        } else {
98            b -= a;
99            s -= u;
100            t -= v;
101        }
102    }
103    (a << k, s, t)
104}
105
106pub fn modinv_recurse(a: u64, m: u64) -> u64 {
107    (extgcd_recurse(a as i64, m as i64).1 % m as i64 + m as i64) as u64 % m
108}