龟速乘(防止爆long long)

快速乘

在某些乘数特别大的情况,比如题目给定的模数大于 \(10^9\) ,在之后的乘法计算中可能会爆 \(long \ long\) ,可以使用 \(O(1)\) 快速乘在不爆 \(long \ long\) 的情况下算出取模后的值。

typedef long long ll;
inline ll mul(ll a,ll b,ll mod){
	return (a*b-(ll)((long double)a/mod*b)*mod+mod)%mod;
}

龟速乘

更多情况下,如果模数稍微比 \(10^9\) 大,如 \(2 * 10 ^ 9\),同样会爆long long,这时候可以使用龟速乘,也就是把 \(b\) 拆分成二进制,一边加一边取模。

typedef long long ll;
ll mul (ll a, ll b, ll mod) { // 防止爆long long
    if(b < 0) a = -a, b = -b;
    ll s = 0;
    for (; b; b >>= 1, a = (a + a) % mod)
        if (b & 1) s = (s + a) % mod;
    return s;
}

posted @ 2021-11-20 14:18  Horb7  阅读(303)  评论(0编辑  收藏  举报