ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • extendedEuclid, crt
    232's competitive-programming templates. 2024. 8. 5. 19:49
    using Num_t = long long;
    
    static_assert(std::is_signed_v<Num_t>);
    
    std::pair<Num_t, Num_t> extendedEuclid(Num_t a, Num_t b) {
      Num_t ua = 1; Num_t va = 0;
      Num_t ub = 0; Num_t vb = 1;
      while (b != 0) {
        Num_t t = a / b;
        a -= t * b;
        ua -= t * ub;
        va -= t * vb;
        std::swap(a, b);
        std::swap(ua, ub);
        std::swap(va, vb);
      }
      if (a < 0) {
        ua = -ua;
        va = -va;
      }
      return {ua, va};
    }
    
    std::pair<Num_t, Num_t> crt(Num_t x0, Num_t m0, Num_t x1, Num_t m1) { /* m0 * m1 < std::numeric_limits<Num_t>::max() / 2 */
      assert(m0 > 0 && m1 > 0);
      if (m0 < m1) {
        std::swap(x0, x1);
        std::swap(m0, m1);
      }
      x0 %= m0; x1 %= m1;
      auto [t0, t1] = extendedEuclid(m0, m1);
      Num_t g = t0 * m0 + t1 * m1;
      if ((x1 - x0) % g != 0) {
        return {-1, -1};
      }
      Num_t resm = m0 * m1 / g;
      Num_t res = x0 + t0 * ((x1 - x0) / g) % m1 * m0;
      res = (res % resm + resm) % resm;
      return {res, resm};
    }
    
    template <typename... Num_ts>
    std::pair<Num_t, Num_t> crt(Num_t x0, Num_t m0, Num_t x1, Num_t m1, Num_ts... args) {
      auto [x, m] = crt(x0, m0, x1, m1);
      if (x == -1) {
        return {-1, -1};
      }
      return crt(x, m, args...);
    }

    '232's competitive-programming templates.' 카테고리의 다른 글

    IterativeSegmentTree  (0) 2024.08.11
    PrimePowerCombination (P^E binom)  (0) 2024.08.08
    getMinP  (0) 2024.08.03
    LazySegmentTree  (0) 2024.08.03
    MergeSortTree  (0) 2024.08.03
Designed by Tistory.