Evaluating 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
.
- One way is you sequentially multiple
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:
- If
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)
]
- If
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 most floor(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))
)
Evaluating the modulo part:
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
Code:
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.