ACM Number Theory - Fast Powers

ACM Number Theory - Fast Powers


Fast power definition:

  As the name suggests, fast exponentiation is the nth power of the base to quickly calculate. Its time complexity is O(log₂N), which is a great improvement in efficiency compared to the naive O(N).

principle:

  The following is an introduction to the b power of a:

    Convert b to a binary number . The weight of the ith bit of the binary number is   
    E.g
        
    11 in binary is 1011    
    11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1
    Therefore, we convert a¹¹ into arithmetic   

Fast exponentiation:

1 LL pow_mod(LL a, LL b, LL p){//a的b次方取余p 
2     LL ret = 1;
3     while(b){
4         if(b & 1) ret = (ret * a) % p;
5         a = (a * a) % p;
6         b >>= 1;
7     }
8     return ret;
9 }
View Code

Quick Multiply:

  In order to prevent overflow when seeking , an algorithm called " fast multiplicationa*b \mod{m} " is usually used .

LL mul(LL a, LL b, LL p){//快速乘,计算a*b%p 
    LL ret = 0;
    while(b){
        if(b & 1) ret = (ret + a) % p;
        a = (a + a) % p;
        b >>= 1;
    }
    return ret;
}
View Code

 

  Take a topic as an example, the topic link: http://acm.hdu.edu.cn/showproblem.php?pid=5187

  This question first finds the law, and then combines the fast multiplication and fast power. The general formula of the title is: 2 n -2

 

#include<iostream>
#include <cstdio>
using namespace std;
typedef long long LL;

LL fast_multi(LL m, LL n, LL mod) // fast multiplication 
{
    LL ans = 0 ; // Note that initialization is 0, not 1 
    while (n)
    {
        if (n & 1)
            years += m;
        m = (m + m) % mod; // same as fast exponentiation, but here is adding 
        m %= mod; // modulo, do not exceed the range 
        ans %= mod;
        n >>= 1;
    }
    return ans;
}
LL fast_pow(LL a, LL n, LL mod)//快速幂 
{
    LL ans = 1;
    while (n)
    {
        if (n & 1)
            ans = fast_multi(ans, a, mod); // Can't multiply 
        a directly = fast_multi(a, a, mod);
        ans % = mod;
        a %= mod;
        n >>= 1;
    }
    return ans;
}

intmain ()
{
    LL n, p;
    while (~scanf("%I64d %I64d", &n, &p))
    {
        if (n == 1 ) // Special judgment 
        {
            printf("%I64d\n", 1 % p);
            continue;
        }
        printf( " %I64d\n " , (fast_pow( 2 , n, p) - 2 + p) % p); // At this step, don't be a negative number 
    }
     return  0 ;
}
View Code

 


 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325479070&siteId=291194637