ICPC Notebook

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

View the Project on GitHub tatyam-prime/ICPC_notebook

:heavy_check_mark: Barrett Reduction
(src/modint/BarrettReduction.hpp)

同じ mod でたくさん計算するとき,剰余算を掛け算に変換して高速化する.

使い方

仕組み

余談

ジャッジが Ice Lake より前の Intel の CPU の場合,64 bit 除算が double 除算より 3 倍以上遅いことが知られている.
あまりではなく商が欲しい場合,mod が固定ではない場合,もっと短く書きたい場合は,double 除算や long double 除算を書くと良い.

Verified with

Code

// using u64 = uint64_t;
struct Barrett {  // mod < 2^32
   u64 m, im;
   Barrett(u64 mod) : m(mod), im(-1ULL / m + 1) {}
   // input: a * b < 2^64, output: a * b % mod
   u64 mul(u64 a, u64 b) const {
      a *= b;
      u64 x = ((__uint128_t)a * im) >> 64;
      a -= x * m;
      if((ll)a < 0) a += m;
      return a;
   }
};
#line 1 "src/modint/BarrettReduction.hpp"
// using u64 = uint64_t;
struct Barrett {  // mod < 2^32
   u64 m, im;
   Barrett(u64 mod) : m(mod), im(-1ULL / m + 1) {}
   // input: a * b < 2^64, output: a * b % mod
   u64 mul(u64 a, u64 b) const {
      a *= b;
      u64 x = ((__uint128_t)a * im) >> 64;
      a -= x * m;
      if((ll)a < 0) a += m;
      return a;
   }
};
Back to top page