二分求幂,快速求解a的b次幂

一个引子

如何求得a的b次幂呢,那还不简单,一个for循环就可以实现!

void main(void)
{
    int a, b;
    int ans = 1;
    cin >> a >> b;
    for (int i = 1; i <= b; i++)
    {
        ans *= a;
    }
    cout << ans;
}

那么如何快速的求得a的b次幂呢?上面的代码还可以优化吗?

当然是ok的!下面就介绍一种方法-二分求幂。

二分求幂

所谓二分求幂,即是将b次幂用二进制表示,当二进制位k位为1时,需要累乘a的2^k次方。

下面优化一下上面的代码:

void main(void)
{
    int a, b;
    int ans = 1;
    cin >> a >> b;
    while (b != 0)
    {
        //当二进制位k位为1时,需要累乘a的2^k次方,然后用ans保存
        if (b % 2 == 1)
        {
            ans *= a;
        }
        a *= a;
        //每次除以2,转换成二进制位
        b /= 2;
    }
    cout << ans;
}

举个例子,当b = 5时,b的二进制为101。

循环次数 二进制位 ans值 a值 b值
0 101 1 a 5
1 101 2 a2 2
2 101 2 a4 1
3 101 32 a16 0

从上表我们可以直观的看出5次幂就可以转换为(2^0+2^2),即a的5次幂就转变为a的(2^0+2^2)次幂,即a的2^0与a的2^2的乘积。

再来个例子-巩固

此题来源于九度教程“人见人爱A^B”。

题目描述:

求A^B的最后三位数表示的整数。

输入:

输入数据包含多个测试实例,每个实例占一行,由两个正整数a和b组成,其中(1<=a,b<=10000),如果a = 0,被= 0,则表示输入数据结束,不做处理。

输出:

对于每个测试实例,输出a^b的最后三位表示的整数,每个输出占一行。

样例输入:

2 3

12 6

6789 10000

0 0

样例输出:

8

984

1

对于这道题,完全可以用上面的二分求解方法,可以仿照上面的代码进行实现。但是有一点需要注意的是,我们不肯能定义一个整型变量或者long long类型的变量取保存如样例给出的数据a = 6789,b=10000,a^b的计算结果。因为数字太庞大了,在整数范围内是无法表示的。所以我们可以只保存每次计算结果的后三位,因为最终结果的后三位取决于其中间值的后三位。

好吧,给出代码:

void main(void)
{
    int a, b;
    while ((cin >> a >> b))
    {
        int ans = 1;
        if (a == 0 && b == 0)
            break;
        while (b != 0)
        {
            //当二进制位k位为1时,就累加a的2^k次方
            if (b % 2 == 1)
            {
                ans *= a;
                ans %= 1000;
            }
            a *= a;
            a %= 1000;
            //每次除以2,转换成二进制位
            b /= 2;
        }
        cout << ans;
    }

}
时间: 2024-12-26 17:55:25

二分求幂,快速求解a的b次幂的相关文章

HDU - 1588 Gauss Fibonacci (矩阵快速幂+二分求等比数列和)

Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r a very clever boy. So if you wanna me be your GF, you should solve the problem called GF~. " How good an opportunity that Gardon can not give up! The "Prob

POJ 3233-Matrix Power Series(矩阵快速幂+二分求矩阵和)

Matrix Power Series Time Limit:3000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3233 Appoint description:  System Crawler  (2015-02-28) Description Given a n × n matrix A and a positive integer k, find the

二分求幂(快速求幂,二进制求幂)

二分求幂, 非递归求法(二进制求法): 比如 2^5就是5个2相乘,按照5的二进制求 3^10就是8个3相乘,再2个3相乘. 处理幂的二进制,具体实现代码如下: long long quickmulti(long long a,long long b) { long long res=1; while(b) { if(b&1) //如果最后一位为1,则res*=a; res*=a; a*=a; //a*=a b>>=1; //b%=2 } return res; }

SPOJ AMR10E Stocks Prediction --二分求和+矩阵快速幂

题意:给一个递推式S(n) = a1*S(n-1)+...+aR*S(n-R),要求S(k)+S(2k)+...+S(nk)的值. 分析:看到n的大小和递推式,容易想到矩阵快速幂.但是如何转化呢? 首先看到 我们用A表示上面的递推式中的R*R的那个矩阵,那么对于前面那个向量,每次乘上A^k之后都会变成(S(n + k)...)那么对于初始的向量( S(R) S(R - 1) ... S(1) ) 如果这个向量当中包括 S(k) 我们可以直接对于每次要算的 S( i * k) 求和也就是说这个向量

二分求幂

2017-07-20 17:47:25 writer:pprp 介绍:二分求幂原理: 一般用递归求解: 代码如下: int power(ll base,unsigned int exponent) { if(exponent == 0) { return 1; } if(exponent == 1) { return base; } double result = power(base,exponent>>1); result *= result; if(exponent%2 == 1) re

算法录 之 快速幂快速乘和矩阵快速幂。

1: 问题如下: 求 a^n % m 的值是多少?n是1到10^18次方的一个整数. 求一个数的n次方,朴素的算法就是直接for循环,O(N)的复杂度. 但是对于这个问题n实在是太大了,O(N)也会超时,那么需要更快的算法,快速幂算法. 要求 a^n,如果知道了 a^(n/2) 次方的话,再来个平方就可以了. 那么按照这个思路就能运用分治的思想了. 代码如下: 1 int _pow(int a,long long n,int m) { 2 if(n==0) return 1 % m; 3 4 l

D是10^k的约数快速求解整除性问题

[D是10^k的约数快速求解整除性问题] 定理: 证明: 例一: 例二: 例三:

hdu 3641 数论 二分求符合条件的最小值数学杂题

http://acm.hdu.edu.cn/showproblem.php?pid=3641 学到: 1.二分求符合条件的最小值 /*==================================================== 二分查找符合条件的最小值 ======================================================*/ ll solve() { __int64 low = 0, high = INF, mid ; while(low <=

bzoj1692: [Usaco2007 Dec]队列变换(hash+二分求LCP)

以前一直用SA求LCP,今天学习了一波hash+二分求LCP的姿势,也是nlogn而且常数更小了. hash+二分可以logn比较两个后缀的字典序大小,求出LCP然后比较LCP后一个字符的字典序 #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #define ull unsigned long long using namespace std; ull mul[1