编程语言
首页 > 编程语言> > 算法_次方求模(快速幂)

算法_次方求模(快速幂)

作者:互联网

求ab % c 的值。其中a, b, c 是整数,且 0 < a,c < 109,0 < b < 1018

暴力算法 O(b)

long long ans = 1;
for (long long i = 1; i <= b; i++)
{
    ans *= a;
}
ans % c;

优化(暴力算法)

根据取模运算的性质,(a * b) % p = [(a % p) (b % p)] % p

所以原式(a · a · a ····· · a)% c ,每乘一次都取模一次,结果不变

long long ans = 1;
for (long long i = 1; i <= b; i++)
{
    ans *= a;
    ans %= c;
}
ans % c;

但复杂度仍然为O(b)

继续优化(快速幂)

计算310 时,手算为—— 310 = (32)5 = 95 = 9 * 94 = 9 * (81)2 = 9 * (812)1

即:①指数为偶数时:指数除以2,底数平方;②指数为奇数时:ans * 底数 *( 指数除以2,底数平方)

#include <iostream>
using namespace std;

typedef long long ll;

ll fast_power(ll a, ll b, ll p)
{
    ll ans = 1;  //初值为1,  因为后续做的是乘法 
    a %= p;
    while(b) // 在b不为0时,做b的奇偶性判断 
    {
        if (b % 2 == 1) //若为奇数  这里可以改成 (b & 1), 在二进制下,奇数最后一位 1 & 1 = 1;偶数最后一位 0 & 1 = 0 
        {
            ans = (ans * a)% p;
        }
        a = (a * a) % p;
        b /= 2;  //等价 b >> 1;  二进制中就是右移一位 
    }
    return ans;
}

int main()
{
    ll a, b, p;
    cin >> a >> b >> p;
    cout << a << "^" << b << " mod " << p << "=" << fast_power(a, b, p);
}

 

标签:求模,奇数,ll,底数,long,算法,ans,次方
来源: https://www.cnblogs.com/baicang/p/15085133.html