快速幂-demo

原创 2016年08月28日 20:59:16

问题描述

本文主要给出快速幂以及快速幂结合求模操作的一般方法

思路

当幂的数字太大时,计算的次数较大。
需要简化计算,可以采用快速幂。
二分幂的办法。

下面这是一种思路:
当b较大时,将其进行分解。

1. b为偶数时,a^b = a^(b/2) * a^(b/2)
2. b为奇数时,a^b = a^(b/2) * a^(b/2) * a

可用递归实现。
如果用非递归可在递归的基础上进行修改。但是要小心奇数和偶数的区别。
所以,还是要借助一个栈来实现。效率并不高。

下面讲另外一种思路:
主要思路是:
将a^b分解为若干个a^(2^k)项的乘积,也体现了分治的思想。
具体来说是在指数层面,将b分解为若干项(2^k)的和。

比如下面的例子:
3 ^ 999 = (3 ^ 512) * (3 ^ 256) * (3 ^ 128) * (3 ^ 64) * (3 ^ 32) * (3 ^ 4) * (3 ^ 2) * 3
= 3 ^ (512 + 256 + 128 + 64 + 32 + 4 + 2 + 1)

对于指数b的分解本质是求b的二进制形式
之所以写成二进制形式的好处是,前一位都可以由后一位的乘积构成。注意这里已经不是在指数层面了。
怎么判断哪一位的权出现,就看分解后相应二进制位是否有效。

看下面的问题: [ jobdu-1441]

题目描述:
求A^B的最后三位数表示的整数。说明:A^B的含义是“A的B次方”
输入:
输入数据包含多个测试实例,每个实例占一行,由两个正整数A和B组成(1<=A,B<=10000),如果A=0, B=0,则表示输入数据的结束,不做处理。
输出:
对于每个测试实例,请输出A^B的最后三位表示的整数,每个输出占一行。
样例输入:
2 3
12 6
6789 10000
0 0
样例输出:
8
984
1

方法一

 int fast_pow( int a, int b, int mod )
{
    if(1==b)
        return a%mod;
    else
    {
        int t = fast_pow( a, b/2, mod );
        if( b%2 )
            return ((t%mod)*(t%mod)*(a%mod))%mod;
        else
            return ((t%mod)*(t%mod))%mod;
    }
}
int fast_pow_without_recursion( int a, int b, int mod )
{
    std::stack<int> stk;
    while( b > 1 )
    {
        stk.push(b%2);
        b /= 2;
    }

    int ans = a%mod;
    while( !stk.empty() )
    {
        int t = stk.top();
        stk.pop();

        if(t%2)
            ans = (ans%mod * ans%mod * a%mod)%mod;
        else
            ans = (ans%mod * ans%mod)%mod ;
    }
    return ans;
}

方法二

int fast_pow1( int a, int b, int mod )
{
    int ans = 1;
    int w = a;
    while( b )
    {
        if(b%2)
            ans = (ans * w%mod)%mod;
        w *= w;
        b /= 2;
    }
    return ans;
}

这个方法,看起来逻辑并没有问题。但是在调试的时候最后一组数据没有过。

1. 边界数据的问题
2. 中间值w*w过大

仔细分析后发现,由于每一个中间项都是由前一项平方得来。所以,加载这一项的求mod。
可以移到前面去。并且,最后一组数据爆了的原因就是,a很大之后w*w很容易直接爆掉。
所以,把求mod放在这里是正确的。应该可以解决之前的问题。

int fast_pow2( int a, int b, int mod )
{
    int ans = 1;
    int w = a;
    while( b )
    {
        if(b%2)
            ans = (ans * w)%mod;
        w = (w%mod * w%mod)%mod;
        b /= 2;
    }
    return ans;
}

总结

刷题一定要有耐心,就像对于方法二。满怀信心,觉得逻辑没有任何错误。但是还是有问题。不能直接百度,一定要自己反复思考,别害怕浪费时间。出来混的早晚都是要还的。虽然最后一点想了好久,但是最后还是想出来了,现在看来也许是轻而易举的事,但是你没到那个程度肯定是不行的。有问题是好事,有问题就能提高。享受解决问题的过程,这就是游戏,看你怎么玩。


版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

快速幂-demo

问题描述 本文主要给出快速幂以及快速幂结合求模操作的一般方法 思路当幂的数字太大时,计算的次数较大。 需要简化计算,可以采用快速幂。 二分幂的办法。下面这是一种思路: 当b较大时,将其进行分...

快速幂&幂模

快速幂

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

矩阵快速幂(poj3070)、快速幂

#include const int mod=10000; struct matrix { int a[2][2]; }origin,res; struct matrix multiply(...
  • myzts
  • myzts
  • 2014-12-29 23:40
  • 323

二分幂,快速幂,矩阵快速幂,快速乘

前言二分幂,快速幂,矩阵快速幂在算大指数次方时是很高效的。求 a^n 的值是多少?n是1到10^18次方的一个整数。   求一个数的n次方,朴素的算法就是直接for循环,一遍一遍的乘,a*a*a*a...

快速幂 + 快速幂取模

1.最一般的求a的b次方  __int64 Pow1(int a,int b) { __int64 ans; while(b--){ ans *= a; } return ans; ...

快速幂或者矩阵快速幂

快速幂或者矩阵快速幂在算指数时是很高效的,他的基本原理是二进制,下面的A可以是一个数也可以是一个矩阵(本文特指方阵),若是数就是快速幂算法,若是矩阵就是矩阵快速幂算法,用c++只需把矩阵设成一个类就可...

快速幂和矩阵快速幂

原文: http://blog.csdn.net/hikean/article/details/9749391

jiulianhuan 快速幂--矩阵快速幂

题目信息: 1471: Jiulianhuan 时间限制: 1 Sec  内存限制: 128 MB 提交: 95  解决: 22 题目描述   For each da...

快速幂 快速幂取模

求x^m 一般方法是 xm = x * xm-1,这样需要做m次乘法,未免过慢。加速方法有两种。1.基于当m为偶数时, xm = (x2)^(m/2) ;当m为奇数时, xm = x * xm-1。显...

快速幂 快速幂取模

快速幂的思想在于快速求解高幂指数的幂运算 复杂度为O(log2n) 与朴素运算相比有很大的改进 接下来给出代码 其中有详解 #include #include using namespace ...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)