Two lines of code implement fast power (mode m) Algorithm

  We know, for a p evaluation (p> 0), the simple exponentiation algorithm uses recursive way, base number is about a multiplicative index p times as a result. The time complexity of this algorithm is O (p), when the index p is large (> 1e7), even if the algorithm has a time complexity is linear in the current machines still spend a lot of computation time.

  Power is required for naive algorithm is improved, is an efficient way to partition: when p is an even number, directly to a p into (a p / 2 ) * (a p / 2 ) in two parts, and each a p / 2 but also to continue to do division, until it became a power; when p is odd, we propose a a, then the rest of the a p-1 becomes a dual exponential form, return to the previous situation; when the index is 0 , it can easily argue that the result is 1. Finally, the separation of each step and then merge the results can be. Thus, we can write recursive mathematical expression:

 

  The time complexity of the partition Solution O (log p), the result in terms of linear complexity has been greatly improved as compared to, for example, can be derived as a result when the index p = 18,446,744,073,709,551,616, only 64 multiplications are calculated.

  How to implement this algorithm do? First think recursively deal with this problem: Note that for large computation result, high-precision analog computation should be considered, or consider the end of this algorithm modulo m.

typedef long long ll;

ll fspow(ll a, ll p) {
    if(p==0)
        return 1;
    if(p&1) {
        ll t = fspow(a, p-1);
        return t*a;
    } else {
        ll t = fspow(a, p/2);
        return t*t;
    }
}

  Many people have a conflict on intuition recursive, recursive considered inefficient. Actually not always the case. We know the time function call overhead is mainly reflected in two aspects: 1, the call stack will save a function parameter, local variables, return address and other information, which needs to be implemented by high-latency memory access instructions; 2, a branch instruction resulting in additional overhead, such as branch prediction due to the failure of the pipeline due to scour and so on.

  But the fact is, if the data size is large compared to accidentally original O (log p) algorithms written alive waste O (p) of the resulting algorithm, the cost of these caused by the underlying system is negligible . Unless you are faced with very limited resources system, or you want to limit optimization of card data, or do not care about spending time recursive call. Of course, it must be considered a recursive spatial complexity.

 

  Recursive algorithm will take up stack space to grow, and this is what we do not want to see. Whether there is a not only kept simple and elegant, but also has a fast constant power algorithm space complexity of it?

  This is a non-recursive version of fast power algorithm. The following two lines of code have been concentrated in the core to the extreme:

1 for (s=1; p;p/=2,a=a*a)
2         if (p&1) s=s*a;

  Wherein a is the base number, p is the index, the algorithm ends, a S = P .

  Let's look at the principle of the algorithm. The idea is still the divide and conquer, which is consistent with our previous discussion, the difference is no longer recursively solved.

  Essence "minute" is the binary index, where the index must be even. When the index halved, to make the results of the same power, base number must be square. Formal description . The index p / 2 but also continue to be divided into p / 4 p / 8 ...... 1 , the base number multiplied by constantly tired. Index will be 1, the result is the base number required. When the index is not even, the first demolition of a base number, the remaining power is an even power, then you can deal with the above method.

  Code involves some tips:

    1. The use of divisible operator / is rounded down features. When the exponent p is an odd number, the results of p / 2 is substantially equal to p-1/2, which eliminates removed when we need a p minus one base-trouble. In fact, since the divisor is 2, can also be written p >> = 1, essentially using the binary division.

    2. We know that the% operator overhead is great, just to determine where parity of p, p binary directly determine the lowest bit.

 

application

  Power operation on many occasions have important applications. E.g. RSA asymmetric encryption algorithm, encrypts the plaintext by the following formula:

C i  = M i e  mod n

    Wherein ciphertext Ci, Mi value associated with the plain text, (e, n) of the public key pair.

  And decrypting the ciphertext by the following formula:

Mi = Cid mod n

  Wherein Mi is the value associated with the plain text, (d, n) is the private key pair.

 

  We can see that both the encryption or decryption, to be used in exponentiation and modular arithmetic. This is our fast exponentiation described above is useful association.

 

  Than the RSA, often the use of other types of the form, as they are attributed to the following formula down:

A P mod a

  Since the exponentiation modulo a result, the end result is not greater than and equal to k. Look at our fast power algorithm, intermediate results are likely much larger than k, if the intermediate result exceeds the range of basic data types, but also by high-precision analog operation, it is unnecessary and a waste of time. So fast power algorithm above, there is room for optimization.

  Number theory pointed out, ( A * b) k = MOD (A MOD k) * (b k MOD) MOD k . I.e. product of two numbers modulo again, two numbers are equal then multiplied modulo, and modulus. Using this nature, we can A P MOD K equivalent deformed (A MOD K) P MOD K, while each time to do multiplication, are first reduced multiplier utilizing this property, and then multiplied.

  The code is modified

1 a %= k;
2 for (s=1; p;p/=2,a=(a*a)%k)
3          if (p&1) s=(s*a)%k;

  Wherein the meaning of a, p, k, s consistent with the above.

  This is a non-recursive algorithm for fast modular exponentiation of k.

 

 

Guess you like

Origin www.cnblogs.com/sci-dev/p/11809300.html