A * B mod C quick calculation method
17:11:18 | category: classic algorithm | Tag: | large font size, small/medium subscription
Method 1:
Everyone can think of it. Calculate the value of a * B and then calculate the value of a * B mod C. This is the simplest, but there is a drawback: the value of a * B cannot be too large and may overflow.
Method 2:
Review the knowledge of hexadecimal conversion. Binary Conversion to hexadecimal can be added with the weight of 2 (which seems to be described in this way ). For example, 13 = (1101) 2 = 1*2 ^ 3 + 1*2 ^ 2 + 0*2 ^ 1 + 1*2 ^ 0. Similarly, when we calculate a * B, we can also convert B to the formula of adding 2 ^ n. Therefore, we can convert a * B mod C to [A * (2 ^ b0 + 2 ^ B1 + ...... 2 ^ bn)] mod c = [A * 2 ^ b0 + A * 2 ^ B1 + ...... A * 2 ^ bn] mod C. The formula (a + B) mod c = [(a mod c) + (B mod C)] mod C is used for calculation.
Code:
Int MUL (int A, int B, int C)
{
Int result, TMP;
TMP = A % C;
While (B)
{
If (B & 1) // determine whether to add a * 2 ^ n based on the value of 2 binary digits, because a right shift operation is performed on B, therefore, you only need to judge the last result each time.
{
Result + = TMP;
If (result> = C)
Result-= C;
}
TMP <= 1; // calculate the value of a * 2 ^ n.
If (TMP> = C)
TMP-= C;
B <= 1;
}
Return result;
}
/*
* FZU1759.cpp
*
* Created on: 2011-10-11
* Author: bjfuwangzhu
*/
#include<stdio.h>
#define LL unsigned long long
LL modular_multi(LL a, LL b, LL c) {
LL res;
res = 0;
while (b) {
if (b & 1) {
res += a;
if (res >= c) {
res -= c;
}
}
a <<= 1;
if (a >= c) {
a -= c;
}
b >>= 1;
}
return res;
}
LL modular_exp(LL a, LL b, LL c) {
LL res, temp;
res = 1 % c, temp = a % c;
while (b) {
if (b & 1) {
res = modular_multi(res, temp, c);
}
temp = modular_multi(temp, temp, c);
b >>= 1;
}
return res;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
LL a, b, c;
while (~scanf("%I64u %I64u %I64u", &a, &b, &c)) {
printf("%I64u\n", modular_exp(a, b, c));
}
return 0;
}