使用二进制将乘法转换为加法,既可以加快速度也能防止乘法溢出
ll mul(ll a, ll b, ll mod){
a %= mod;
b %= mod;
ll res = 0;
while (b){
if (b&1){
res += a;
if (res >= mod) res -= mod;
}
b >>= 1;
a <<= 1;
if (a >= mod) a -= mod;
}
return mod;
}
//使用快速乘法优化快速幂
ll qpow(ll a,ll b,ll mod){
ll ans = 1;
while (b){
if (b&1) ans = mul(ans,a,mod);
a = mul(a,a,mod);
b >>= 1;
}
return ans;
}
//单纯防止数值溢出的快速乘法
ll qmul(ll x,ll y,ll mod){
return (x * y - (ll)(x / (long double)mod * y + 1e-1) * mod + mod) % mod;
}