Reputation: 129
I am solving a programming problem where I have to print the answer in the format answer mod 10 ^ 9 + 7, where 'answer' is the actual answer to the problem.
I have figured out the algorithm to solve the problem, however the caveat is that the answer to the problem is always of the format m * 10 ^ n, where
1 <= m <= 8 and 2 <= n <= 10 ^ 18, that is in the answer 10 can be raised to a power as large as 10 ^ 18. Ofcourse, directly calculating 10 ^ n may overflow.
What should I do next?
Upvotes: 0
Views: 4043
Reputation: 1031
10^n mod M
:What you need is Modular Exponentiation. It can compute (a^b)%m
in log_2(b)
(log base 2).
Example
Let's say you need to compute 10^9
.
10
, 9
times.Or, use divide and conquer approach.
10^9 = (10^8)*(10^1)
10^8 = (10^4)*(10^4)
: Do you need to compute 10^4
twice?
10^4 = (10^2)*(10^2)
: Do you need to compute 10^2
twice?
10^2 = (10^1)*(10^1)
10^1 = (10^1)*(10^0)
10^0
is the base case.
So, what we basically do is:
power
is an odd number, then we compute base^(power-1)
and multiply it with base
to get base^power
. [base^power = (base^(power-1)) * base)
]power
is an even number, then we compute base^(power/2)
and multiply it with itself to get base^power
. [base^power = (base^(power/2)) * (base^(power/2))
]. But we compute base^(power/2)
only once.Computational Complexity:
As stated here:
A brief analysis shows that such an algorithm uses
floor(log_2(n))
squarings and at mostfloor(log_2(n))
multiplications. More precisely, the number of multiplications is one less than the number of ones present in the binary expansion of n.
So, we can say that the runtime is of the order of log_2(n)
. (O(log_2(power))
)
It is easy to notice that while computing a value as large as 10^(10^18)
, we are bound to overflow even largest of the primitive types (long long int
). And here enters the Modular Multiplication, according to which (a * b) % c = ((a % c) * (b % c)) % c
. As a side note, you might not see this rule in use when you directly look at code, but it is being used if you evalute the recursive calls.
Problem solved?
We prevent overflow by computing the modulo on the run. Say, if we got some value as 10^9
and we need to multiply it with itself. Overflow? Nah, not this time.
ans = ((10^9 % 1000000007) * (10^9 % 1000000007)) % 1000000007
ans = 10^18 % 1000000007
ans = 49
While there are multiple implementations, here is a simple one:
const int M = 1e9 + 7;
long long int powxy(long long int x, long long int y) {
if (y == 0) return 1;
if (y%2 == 1) return (x*powxy(x, y-1))%M;
long long int t = powxy(x, y/2);
return (t*t)%M;
}
Tested here.
Upvotes: 3