快速幂

关于快速幂的问题其实很早之前就已经遇到过了,但是当时怎么说呢?天真单纯,涉世不深(就是傻),只是一味地想着直接用循环去直接乘(越说越觉得自己是个傻子)

直接进入正题:
所谓快速幂运算,就是将大幂转小幂,就是 a^x=a^{x_1+x_2},而这里用的分解方法是二进制的,如(11)_{10}=(1101)_2,其中11=8+2+1。为什么这么分,是因为a*a=a^2,a^2 * a^2 = a^4….,这样划分本来要做11次的乘法,直接简化为6次乘法。而在次数更高的情况下,简化的效果更明显。

这里要用一个与运算和移位运算,还是上面的例子。1101 & 0001 =0001,即其第一位有1的出现,则要乘以其一次方,再一位 1101变成110,在与1相与,以此类推。

上代码:

ll quickpower(ll a, ll b)     //快速计算a^b
{
    ll ans = 1;
    ll temp = a;
    while (b > 0)
    {
        if (b & 1)
            ans *= temp;
        temp *= temp;
        b >>= 1;
    }
    return ans;
}

取余运算

取余运算就很基础了,但鄙人想说的是将快速幂鱼取余运算结合
首先先看一下取余运算的运算规则:

(A+B) mod C=(A mod C+B mod C) mod C
(A*B) mod C=(A mod C * B mod C) mod C

上代码:

ll quickpower_mod(ll a, ll b, ll c)
{
    ll ans = 1;
    ll temp = a;
    while (b)
    {
        if (b & 1)
        {
            ans *= temp;
            ans %= c;
        }
        temp *= temp;
        temp %= c;
        b >>= 1;
    }
    return ans % c;
}

完整代码来一波

#include <iostream>
#include <algorithm>

using namespace std;
typedef long long ll;

ll quickpower(ll a, ll b)     //快速计算a^b
{
    ll ans = 1;
    ll temp = a;
    while (b > 0)
    {
        if (b & 1)
            ans *= temp;
        temp *= temp;
        b >>= 1;
    }
    return ans;

}

ll quickpower_mod(ll a, ll b, ll c)
{
    ll ans = 1;
    ll temp = a;
    while (b)
    {
        if (b & 1)
        {
            ans *= temp;
            ans %= c;
        }
        temp *= temp;
        temp %= c;
        b >>= 1;
    }
    return ans % c;
}



int main()
{
    ll a, b, c, ans;
    cin >> a >> b>>c;
    ans=quickpower_mod(a, b, c);
    cout << a << '^' << b << " mod " << c << '=' << ans;
    return 0;

}

打完收工

分类: 算法集

0 条评论

发表评论

Avatar placeholder

邮箱地址不会被公开。 必填项已用*标注