参见英文答案 >
Need help in mod 1000000007 questions3个
> How can I calculate (A*B)%C for A,B,C <= 10^18,in C++?2个
> Compute (a*b)%m FAST for 64-bit unsigned arguments in C(++) on x86-64 platforms?4个
是的我知道这个问题可能看起来很幼稚但我在谷歌和这个网站上搜索了很多但是找不到令人满意的答案.
我只想计算(A * B)%MOD,假设a长很长,那么b和MOD也是如此.
假设MOD大于A和B,使得A%MOD = A且B%MOD = B但A * B大于64位.如何计算(A * B)%MOD的正确值?
> How can I calculate (A*B)%C for A,B,C <= 10^18,in C++?2个
> Compute (a*b)%m FAST for 64-bit unsigned arguments in C(++) on x86-64 platforms?4个
是的我知道这个问题可能看起来很幼稚但我在谷歌和这个网站上搜索了很多但是找不到令人满意的答案.
我只想计算(A * B)%MOD,假设a长很长,那么b和MOD也是如此.
假设MOD大于A和B,使得A%MOD = A且B%MOD = B但A * B大于64位.如何计算(A * B)%MOD的正确值?
解决方法
这里的基本思想是首先定义一个非溢出的addmod函数,该函数利用其算术中的负数.然后根据它使用位操作定义timesmod.时间复杂度为O(N),其中N是使用的比特数(在这种情况下为64).
#include <iostream> using namespace std; typedef long long BigInt; // must be signed,to detect overflow BigInt A = 0x7fffffffffffff01; BigInt B = 0x7fffffffffffff02; BigInt M = 0x7fffffffffffff03; // For simplicity it is assumed x,y,and m are all positive. BigInt addmod( BigInt x,BigInt y,BigInt m ) { x %= m; y %= m; BigInt sum = x-m+y; // -m <= sum < m-1 return sum < 0 ? sum + m : sum; } BigInt timesmod( BigInt x,BigInt m ) { x %= m; y %= m; BigInt a = x < y ? x : y; // min BigInt b = x < y ? y : x; // max BigInt product = 0; for (; a != 0; a >>= 1,b = addmod(b,b,m) ) if (a&1) product = addmod(product,m); return product; } int main() { cout << "A = " << A << endl; cout << "B = " << B << endl; cout << "M = " << M << endl; cout << "A*B mod M = " << timesmod(A,M) << endl; return 0; }
输出:
A = 9223372036854775553 B = 9223372036854775554 M = 9223372036854775555 A*B mod M = 2
这很容易确认,因为A = -2且B = -1 mod M.
注意:此代码未进行优化.