with ; it runs in steps (worst case: consecutive Fibonacci numbers). The extended Euclid algorithm also returns Bézout coefficients , which give modular inverses, linear Diophantine equations and CRT (Congruences and CRT).

ll extgcd(ll a, ll b, ll& x, ll& y) {                     // returns g = gcd(a, b) >= 0 and a x + b y = g
    x = 1, y = 0; ll x1 = 0, y1 = 1;                      // the quotients q below are exactly a/b's continued-fraction expansion
    while (b) { ll q = a / b; tie(a, b) = make_pair(b, a - q * b); tie(x, x1) = make_pair(x1, x - q * x1); tie(y, y1) = make_pair(y1, y - q * y1); }
    if (a < 0) a = -a, x = -x, y = -y;
    return a;
}
ll invMod(ll a, ll m) { ll x, y; ll g = extgcd(((a % m) + m) % m, m, x, y); return g != 1 ? -1 : ((x % m) + m) % m; }
ull binaryGcd(ull a, ull b) {                             // Stein: shifts and subtractions only
    if (!a || !b) return a | b;
    int s = __builtin_ctzll(a | b); a >>= __builtin_ctzll(a);
    while (b) { b >>= __builtin_ctzll(b); if (a > b) swap(a, b); b -= a; }
    return a << s;
}
ll lcmSafe(ll a, ll b) { return a / std::gcd(a, b) * b; }  // divide first; check against a bound with __int128 if needed
PropertyStatement
basic divisibility and and ; and (transitive); and
Bézout: the smallest positive combination is ; is solvable iff
every common divisor divides so is the greatest in the divisibility order
coefficient sizethe returned $
scaling, coprimality;
shifting
Euclid’s lemma prime, or ;
products$\gcd(a, b)\cdot\text{lcm}(a, b) =
arrays (range add keeps the differences)
lattice pointsthe segment – contains lattice points
special sequences;
subarray gcdsthe gcds of subarrays ending at take distinct values

Patterns

vector<pair<ll, ll>> subarrayGcdCounts(const vector<ll>& a) {   // {g, number of subarrays with gcd g}
    map<ll, ll> total; vector<pair<ll, ll>> cur;           // (gcd, count) of subarrays ending at i
    for (ll x : a) {
        vector<pair<ll, ll>> nxt{{x, 1}};
        for (auto [g, c] : cur) { ll h = std::gcd(g, x); if (nxt.back().first == h) nxt.back().second += c; else nxt.push_back({h, c}); }
        for (auto [g, c] : nxt) total[g] += c;
        cur = move(nxt);
    }
    return vector<pair<ll, ll>>(all(total));
}
vector<ll> divisorsOf(ll n) {                             // O(sqrt n), sorted
    vector<ll> small, big;
    for (ll d = 1; d * d <= n; d++) if (n % d == 0) { small.push_back(d); if (d != n / d) big.push_back(n / d); }
    small.insert(small.end(), big.rbegin(), big.rend()); return small;
}
max divisor count 322401344672026880103680

for any (sub-polynomial), though is a practical rule of thumb at contest-sized ; the divisor-pair sum drives most sieve-style precomputation (Floor Sums).

  • GCD of a range: sparse table (idempotent) in per query after , or a segment tree with point updates.
  • Range add + range gcd: keep a segment tree of differences: .
  • Counting pairs with : Möbius over multiples (Arithmetic Functions).
  • Generalised Euclid / floor sums run the same recursion on (Floor Sums).