barrett 模乘
可以在输入模数题中加速取模,实测大概快两倍左右。
做法是这样的:
\[\begin{aligned}
&x \bmod M
\\
=& x - M \cdot (x/M)
\\
=& x - M \cdot (((2^{64}x)/M)/2^{64})
\end{aligned}
\]
然后这里把 \(x\) 提出来,预处理 \(\mu = 2^{64}/M\) 的值,得到
\[\begin{aligned}
&x \bmod M
\\
\approx& x - M \cdot (x \cdot \mu / 2^{64})
\end{aligned}
\]
实现:
int mod;
__int128 mu;
inline void init_Mod() {mu=(((__int128)1<<64))/mod;}
inline ull Mod(ull x) {return x-mod*(((__int128)x*mu)>>64);}
会存在至多 \(1\) 个 \(mod\) 的误差,所以可能需要在输出答案之前,整体做一次模加模。

浙公网安备 33010602011771号