Evaluate a ^ B mod C
Algorithm 1.
First, design the algorithm directly:
int ans=1, i; for(i=1;i<=b;i++) ans*=a; ans%=c;
View code
The time complexity of this algorithm is reflected in the for loop, which is O (B ).
This algorithm has obvious problems. If a and B are too large, it will easily overflow.
Let's take a look at the first Improvement Solution: before talking about this solution, we should first have a formula like this:
A ^ B mod c = (a mod c) ^ B
Theorem:
(A * B) mod c = [(a mod c) * (B mod C)] mod C;
Proof: Set a mod c = D, B mod c = E;
Then: A = T * C + D; B = K * C + E;
(A * B) mod c = (T * C + D) (T * C + E)
= (Tk c ^ 2 + (Te + DK) * C + D * E) mod C
= De mod C
That is, the remainder of the product is equal to the remainder of the product.
(A ^ B) mod C can be obtained through iteration of the above formula (a mod c) ^ B.
After the above formula is proved, we can let a get the remainder of C first, which can greatly reduce the size of a, so we do not have to think about the improvement:
Algorithm 2:
Int ans = 1, I; A = A % C; // Add this sentence for (I = 1; I <= B; I ++) ans = ans *; ans = ans % C;
View code
Since a factor is multiplied by the remainder and then the remainder remains the same, the newly calculated ans can also perform the remainder operation, so we can get a better version.
Algorithm 3:
Int ans = 1, I; A = A % C; For (INT I = 1; I <= B; I ++) ans = (ANS * A) % C; // here, the remainder ans = ans % C is obtained again;
View code
This algorithm has not been improved in terms of time complexity. It is still O (B), but it is much better. However, it is likely to time out when C is too large, we have introduced the following fast power algorithms.
The rapid idempotence relies on the following formula:
Then we can get the following algorithm:
Algorithm 4:
Int ans = 1, I; A = A % C; If (B % 2 = 1) ans = (ANS * A) mod C; // if it is an odd number, if you need to take more steps, you can calculate them to ans in advance. K = (A * A) % C; // we take a ^ 2 instead of a for (I = 1; I <= B/2; I ++) ans = (ANS * k) % C; ans = ans % C;
View code
We can see that we have changed the time complexity to O (B/2 ).
Of course, this is a permanent cure.
But we can see that when we make k = (A * A) mod C, the status has changed and the final result we require is K ^ (B/2) moD C
Instead of the original a ^ B mod C, we found that this process can be iterated. Of course, there will be one more a mod C for the odd number case, so to complete the iteration, when B is an odd number, we use ans = (ANS * A) % C;
To make up for this extra item, then the remaining part can be iterated.
After iteration of the formula above, when B = 0, all the factors are multiplied and the algorithm ends.
Therefore, it can be completed in O (log B) time.
So we have the final algorithm: quick power algorithm.
Algorithm 5: Fast Power Algorithm
int ans = 1; a = a % c; while(b>0) { if(b % 2 == 1) ans = (ans * a) % c; b = b/2; a = (a * a) % c; }
View code
Structure the code above, that is, write it as a function:
long long PowerMod (int a, int b, int c) { int ans = 1; a = a % c; while(b>0) { if(b % 2 = = 1) ans = (ans * a) % c; b = b/2; // b>>=1; a = (a * a) % c; } return ans; }
View code
The time complexity of this algorithm is O (logb), which can be passed in almost all programming (competition) processes. It is one of the most common algorithms currently.
The following content is for reference only:
Extension: There is a derivation of the fast power algorithm. You can also think about it from another perspective.
A ^ B % C to solve this problem, we can also consider the Binary Conversion:
Convert the hexadecimal value of B to 2.
Hexadecimal expression:
Note that an here is either 0 or 1. If it is 0, this item is 1, which corresponds to the case where B is an even number in the above algorithm;
1 corresponds to the case where B is an odd number.