This documentation is automatically generated by online-judge-tools/verification-helper
#include "src/modint/BarrettReduction.hpp"
同じ mod でたくさん計算するとき,剰余算を掛け算に変換して高速化する.
Barrett br(mod)
:Barrett Reduction を準備する.
mod < 2^32
u64 br.mul(u64 a, u64 b)
:a * b % mod
を計算する.
a * b < 2^64
im
には 1.0 / mod
の小数部 64 bit が書かれている.u64 x = ((__uint128_t)a * im) >> 64;
で商を計算している.ジャッジが Ice Lake より前の Intel の CPU の場合,64 bit 除算が double 除算より 3 倍以上遅いことが知られている.
あまりではなく商が欲しい場合,mod が固定ではない場合,もっと短く書きたい場合は,double 除算や long double 除算を書くと良い.
// 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;
}
};