kyopro-lib

This documentation is automatically generated by online-judge-tools/verification-helper

View on GitHub

:warning: Bézout's identity
(Mylib/Number/bezout_identity.cpp)

Operations

$ax + by = c$の形の一次不定方程式を解く。 $c \neq 0 \pmod {gcd(a, b)}$のとき、整数解x, yは存在しない。 そうでなければ、整数解ペアx, yのうちxが最小の非負整数となるものを設定した生成器を返す。

Requirements

Notes

Problems

References

Depends on

Code

#pragma once
#include <optional>
#include <utility>
#include "Mylib/Number/extended_gcd.cpp"

namespace haar_lib {
  struct bezout_generator {
    int64_t a, b, c, x, y, dx, dy;

    auto value() const { return std::make_pair(x, y); }
    auto next(int64_t n = 1) {
      x += dx * n, y -= dy * n;
      return std::make_pair(x, y);
    }
    auto prev(int64_t n = 1) {
      x -= dx * n, y += dy * n;
      return std::make_pair(x, y);
    }
  };

  std::optional<bezout_generator> bezout_identity(int64_t a, int64_t b, int64_t c) {
    auto [g, x, y] = ext_gcd(a, b);

    if (c % g != 0) return std::nullopt;

    int64_t dx = b / g;
    int64_t dy = a / g;
    int64_t dc = c / g;

    x %= dx;
    if (x < 0) {
      x += std::abs(dx);
    }

    x *= dc;
    dx *= dc;
    dy *= dc;

    y = (c - a * x) / b;

    return bezout_generator({a, b, c, x, y, dx, dy});
  }
}  // namespace haar_lib
#line 2 "Mylib/Number/bezout_identity.cpp"
#include <optional>
#include <utility>
#line 2 "Mylib/Number/extended_gcd.cpp"
#include <tuple>

namespace haar_lib {
  auto ext_gcd(int64_t a, int64_t b) -> std::tuple<
      int64_t,  // gcd
      int64_t,  // p
      int64_t   // q
      > {
    if (b == 0) return std::make_tuple(a, 1, 0);
    const auto [d, q, p] = ext_gcd(b, (a + b) % b);
    return std::make_tuple(d, p, q - a / b * p);
  }
}  // namespace haar_lib
#line 5 "Mylib/Number/bezout_identity.cpp"

namespace haar_lib {
  struct bezout_generator {
    int64_t a, b, c, x, y, dx, dy;

    auto value() const { return std::make_pair(x, y); }
    auto next(int64_t n = 1) {
      x += dx * n, y -= dy * n;
      return std::make_pair(x, y);
    }
    auto prev(int64_t n = 1) {
      x -= dx * n, y += dy * n;
      return std::make_pair(x, y);
    }
  };

  std::optional<bezout_generator> bezout_identity(int64_t a, int64_t b, int64_t c) {
    auto [g, x, y] = ext_gcd(a, b);

    if (c % g != 0) return std::nullopt;

    int64_t dx = b / g;
    int64_t dy = a / g;
    int64_t dc = c / g;

    x %= dx;
    if (x < 0) {
      x += std::abs(dx);
    }

    x *= dc;
    dx *= dc;
    dy *= dc;

    y = (c - a * x) / b;

    return bezout_generator({a, b, c, x, y, dx, dy});
  }
}  // namespace haar_lib
Back to top page