一、解题思路
核心:二进制思想
如果直接计算\(a\)乘\(b\)这会超过 \(long\) \(long\) 的最大范围,所以采用类似于快速幂的思想
把\(b\)写成二进制形式,然后如果某位上为\(1\)就加上它\(a*(2^n)\)次方(\(n\)与这位的位置有关)
并且每次计算后取模就可以了。
例:计算 \(3*7\)
\(7\)的二进制 \(111\)
\(3*(2^0)=3\)
\(3*(2^1)=6\)
\(3*(2^2)=12\)
观察可发现每次的可由前一次\(*2\)推出(记得取模)
比如:\(3,6,12,24,...\),其实\(a*b\)可以理解为每次数字\(a\)翻番。类比一下快速幂,那个是\(a*a\),这里是\(a+a\)。
时间复杂度分析:\(logn\)
二、实现代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL a, b, p, res;
int main() {
cin >> a >> b >> p;
while (b) {
if (b & 1) res = (res + a) % p;
a = (a + a) % p;
b >>= 1;
}
cout << res << endl;
return 0;
}