64位整数乘法
Posted mr94kevin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了64位整数乘法相关的知识,希望对你有一定的参考价值。
//总结自李煜东著《算法竞赛进阶指南》
问题:求a乘b对p取模的值,其中1<=a,b,p<=10^18。
简单的暴力相乘显然会溢出(相当于对64位整数最大值+1取模),对a进行b次累加显然会超时。
法一:
仿照快速幂,用二进制表示b。
1 typedef long long ll; 2 3 inline ll mul(ll a, ll b, ll p) { 4 a %= p, b %= p; 5 ll ans = 0; 6 while (b) { 7 if (b & 1) ans = (ans + a) % p; 8 a = a * 2 % p, b >>= 1; 9 } 10 return ans; 11 }
法二:
利用a*b%p=a*b-floor(a*b/p)*p求解,其中floor函数表示向下取整。
1 inline ll mul(ll a, ll b, ll p) { 2 a %= p, b %= p; 3 ll c = (long double)a * b / p; 4 ll ans = a * b - c * p; 5 if (ans < 0) ans += p; 6 else if (ans >= p) ans -= p; 7 return ans; 8 }
值得一提的是,尽管a*b和c*p可能溢出,但这并不影响,因为a*b-c*p一般不会超过p-1,我们只关心他们的低位。
以上是关于64位整数乘法的主要内容,如果未能解决你的问题,请参考以下文章
64位整数乘法讲解-And-AcWing-90. 64位整数乘法-《算法竞赛进阶指南》