菜鸟新人的第一篇博客——关于快速幂

(主要是写给自己看,加深理解顺便记录)

求 a 的 b 次方对 p 取模的值

输入格式
三个整数 a,b,p ,在同一行用空格隔开。

输出格式
输出一个整数,表示a^b mod p的值。

数据范围
1≤a,b,p≤10^9

时/空限制: 1s / 32MB

输入样例:
3 2 7
输出样例:
2

解题思路:
1、取模运算的性质:(ab)%p=[(a%p) * (b%p)]%p
证明:
设a = k1 * p + q1 , b = k2 * p + q2
a * b = ( k1 * k2 * p + k1 * q2 + k2 * q1 ) * p + q1 * q2
所以 ( a * b ) % p = ( q1 * q2 ) % p
有 a % p = q1 , b % p = q2

2、例如计算3^10:
3^10 = ( 3^2 )^5 = 9^5 = 9 * ( 9^2 )^2
指数分奇偶情况

代码实现:

typedef long long ll;
ll power(ll a,ll b,ll p){
    
    
    ll ans=1%p;//若p=1,则1%1=0
    a%=p;
    while(b){
    
    
        if(b%2==1) ans=(ans*a)%p;
        a=(a*a)%p;
        b/=2;
    }
    return ans;
}

改良版代码

typedef long long ll;
ll power(ll a,ll b,ll p){
    
    
    ll ans=1%p;
    a%=p;
    while(b){
    
    
        if(b&1) ans=(ans*a)%p;//判断该二进制位是否为1,即次数是否是奇数
        a=(a*a)%p;
        b>>=1;//位移操作
    }
    return ans;
}

64位整数乘法

类比快速幂
例如讲一个数转化成二进制
11=(1011)=1* 2^3 + 0* 2^2 + 1 * 2^1+1 * 2^0
将b转化为二进制加法表示,再分别与a相乘,最后相加。

typedef long long ll;
ll power(ll a,ll b,ll p){
    
    
    ll ans=0;
    a%=p;
    while(b){
    
    
        if(b&1) ans=(ans+a)%p;
        a=(a*2)%p;
        b>>=1;
    }
    return ans;
}

猜你喜欢

转载自blog.csdn.net/weixin_50931401/article/details/112699367
今日推荐