//CH0102 2020/10/07 21:16
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll a, b, p;
ll qadd (ll x, ll y, ll mod) {
ll ret = 0;
while (y) {
if (y & 1) {
ret = (ret + x) % mod;
}
y >>= 1;
x = (x << 1) % mod;
}
return ret;
}
int main () {
cin >> a >> b >> p;
cout << qadd (a, b, p);
}
类比快速幂思想,把幂运算替换成乘法,乘数y为奇数则加一个x到ans里,乘数y为偶数则把x加倍。
类似于CH0101,本题也有另一种思想,代码实现依然相同。
\(a * b = \sum{a * c_{i} * 2^{i}}\),求出每一个\(a * c_{i} * 2^{i}\)后乘2便可获得更高一位的状况。如果更高一位二进制位存在那么就可以加到答案里。
还有另一种O(n)的算法:
ll c = (long double) x * y / mod;
ll ans = x * y - c * mod;
return ((ans % mod) + mod) % mod;
long double虽然不准确,但是确实足以应对x*y的数据范围,对x*y/mod也可以给出基本准确的值,所以通过这种方法就可以曲线救国实现求模。(ll越界自动求模,对答案没有什么影响,mod一定是小于ll范围的)