CH0102 64位整数乘法 【防爆log乘】

//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范围的)

posted @ 2020-10-07 21:17  maomao9173  阅读(109)  评论(0编辑  收藏  举报