Fast Power operation
In addition to mathematical problems, there are many places where power operations are used. This paper introduces a fast power arithmetic algorithm which can be used to calculate the power operation very efficiently--the method of repeated leveling.
Carmichael number
We have x^n=x (mod n) composite n called Carmichael number for any 1<x<n. For a given integer n, the judge is not Carmichael number.
Restrictions:
2<n<6500
Input 17 Output No (17 is prime)
Input 561 output Yes
Here mod, also can be replaced by%:
The MoD operation, the remainder operation, is an operation that takes an integer x divided by another integer y in an integer operation, regardless of the quotient of the operator. In computer programming, there are mod operations, which means that the remainder of the result is obtained after dividing two integers such as: 7 mod 3 = 1 because 7 divided by 3 quotient 2 + 1, the remainder 1 is the result of the MoD operation. There is a theorem: two numbers multiplied by the remainder equals to the residue multiplied and then taken. There are many similarities with arithmetic
|
|
Binding law |
((a+b) mod p + c) mod p = (A + (b+c) mod p) mod p ((a*b) mod p * c) mod p = (A * (b*c) mod p) mod p |
Exchange Law |
(A + b) mod p = (b+a) mod p (axb) mod p = (BXA) mod p |
Distribution Law |
((a +b) mod pxc) mod p = ((AXC) mod p + (BXC) mod p) mod p (AXB) mod c= (a mod c * b mod c) mod C (a+b) mod c= (a mod c + b mod c) mod C (-a) mod c= (a mod c-b mod c) MoD c |
Let's start with a simple example: ask for x^n% mod.
algorithm 1. First, directly to design this algorithm:
int mod1 (int x,int n,int mod)
{
int ans=1;
for (int i=1;i<=n;i++)
{
ans*=x;
}
return ans%mod;
}
The time complexity of this algorithm is reflected in the For Loop, O (n). There are obvious problems with this algorithm, and if x and N are too large, it can easily overflow.
So, let's take a look at the first improvement scenario: Before you talk about this scenario, there's a formula:
(a*b)%c = ((a%c) *b)%c
This formula we should learn in discrete mathematics or number theory, that is, the product of the remainder equals to take the remainder of the product.
After proving the above formula, we can first let a about the C to take the remainder, this can greatly reduce the size of a, the likelihood of overflow will greatly reduce
So the above program has been improved:
* * Algorithm 2: *
int mod2 (int x,int n,int mod)
{
x=x%mod;///here is the step to improve
int ans=1;
for (int i=1;i<=n;i++)
{
ans*=x;
}
return ans%mod;
}
Smart readers should be able to think of, since a factor after the remainder of the multiplication and then take the rest of the remaining constant, then the new ans can also take redundancy, so get a better version of the improved.
Algorithm 3:
int mod3 (int x,int n,int mod)
{
x=x%mod;///here is the step to improve
int ans=1;
for (int i=1;i<=n;i++)
{
ans= (ans*x)%mod;///again improved
}
return ans%mod;
}
This algorithm is not improved in time complexity, still O (n), but it is much better, but in the case of mods too large, it is still possible to time out, so we introduced the following fast power algorithm.
The fast power algorithm relies on the following obvious formulas, which I will not prove.
A^b mod c= (a^2) ^ (B/2) mod c (b is even);
With the above two formulas, we can draw the following conclusions:
1. If b is an even number, we can remember k = a^2 mod C, then ask (k) ^B/2 mod c to do it.
2. If b is odd, we can also remember k = a^2 mod C, then ask
((k) ^b/2 mod cxa) mod c = ((k) ^b/2 mod cxa) mod c is available.
Then we can get the following algorithm:
Algorithm 4:
int mod4 (int x,int n,int mod)
{
int ans = 1;
x = x% mod;
if (n%2==1)
ans = (ans * x)% MoD;//If it is odd, one more step, you can calculate in advance to the ans
int k = (x*x)% MoD;//We take A2 instead of a for
(int i = 1; i&l T;=N/2; i++)
{
ans = (ans * k)% mod;
}
ans = ans% mod;
return ans;
}
We can see that we turn the complexity of time into O (N/2). Of course, this kind of symptom is not the cure. But we can see that when we make k = (XXX)% mod, the state has changed and the final result we ask for is (k) ^ (N/2)% mod instead of the original (x^n)% mod, so we find that this process can be iterated. Of course, for odd cases there is an extra x mod, so in order to complete the iteration, when n is odd, we pass
Ans = (ans * x)% mod; to make up for the extra, the rest of the section can be iterated.
When the b=0 is down, all the factors are multiplied and the algorithm ends. You can then complete the time in O (log b). So, with the final algorithm: the Fast Power algorithm.
algorithm 5: Fast Power algorithm
int mod5 (int x,int n,int mod)
{
int ans = 1;
x = x% mod;
while (n>0)
{
if (n% 2 = = 1)
ans = (ans * x)% mod;
n = n/2;
x = (x * x)% mod;
}
return ans;
}
The time complexity of this algorithm is O (LOGN), which can be passed in almost all program Design (contest) process, and is one of the most commonly used algorithms at present.
The following information is for reference only:
Extension: There is a derivation of the algorithm for fast power, which can also be thought from another angle.
To solve this problem, we can also consider from the conversion of the binary:
Converts a 10-binary B into an 2-binary expression:
Well, actually,. For example: x^22=x^16xx^4xx^2;
(and 22 is converted to binary number is 10110)
So, notice here is either 0, or 1, if an item, then this is 1, this corresponds to the above algorithm process B is an even number of cases, for 1 corresponds to B is an odd number of cases [do not make the reverse, the reader himself to analyze, you can contact 10 to 2 into the method], we multiply from in turn. For each item's calculation, the result of the last item is calculated using the square of the result of the previous item. For the required result, the last ans does not have to multiply it, [because this is a value of 1], and 1 is multiplied by the remainder of the item.
Of course, the control of n here can be better understood by using binary ideas
algorithm 6:
ll Mod_pow (ll x,ll n,ll MoD)
{
ll res=1;
while (n>0)
{
if (n&1)
res=res*x%mod;
X=x*x%mod;
n>>=1;
}
return res;
}
can also be handed back to achieve
Algorithm 6:
ll Mod_pow1 (ll x,ll n,ll MoD)
{
if (n==0) return 1;
ll Res=mod_pow1 (x*x%mod,n/2,mod);
if (n&1) res=res*x%mod;
return res;
}
Original blog: http://www.cnblogs.com/cmmdc/p/7203852.html