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\) 的误差,所以可能需要在输出答案之前,整体做一次模加模。

posted @ 2026-04-23 19:02  _Bonely_Muffin  阅读(19)  评论(0)    收藏  举报