我找到这两个代码来计算(a * b)%c当a,b,c大约为10 ^ 18时,但无法得到它们如何工作,任何人都能解释我这些函数如何逐行工作
long long int mult(long long int x, long long int y, long long int mod)
{
x = x % mod;
y = y % mod;
long long int z = 0;
for (1; x; x >>= 1){
if(x & 1)
if((z =z+ y) >= mod)
z = z- mod;
if((y = 2 * y) >= mod)
y =y- mod;
}
return z;
}
和
long long multiple(long long a, long long b, long long c) // a * b % c
{
if (b == 0)
return 0;
long long ret = multiple(a, b >> 1, c);
ret = (ret + ret) % c;
if (b & 1)
ret = (ret + a) % c;
return ret;
}
我已经使用这些功能来解决在线比赛,我已经看到第一个功能比后者更好/更快,但为什么呢?
答案 0 :(得分:0)
比特移位将乘法运算转换为(条件)加法。每次循环(第一种方法)或递归调用(第二种方法)时,代码会查看其中一个操作数的最低有效位:如果已设置,则将另一个操作数添加到运行总计中。然后它将第一个操作数向右移动(除以2)并将另一个操作数加倍(如果需要,使用模数或减法)。
例如,如果数字是5和7,5 == 101二进制,那么:
x y z
-- --- ---
101 7 7 (bottom bit set, add 7 to z)
10 14 ( x = x >> 1 ; y = y * 2 )
10 14 7 (bottom bit not set, don't add)
1 28 7 ( x = x >> 1 ; y = y * 2 )
1 28 35 (bottom bit set, add 28 to z)
0 ( x = x >> 1 ; x is zero so stop)