关闭

快速幂取模及其应用

标签: 二进制快速幂namespace斐波那契算法
13610人阅读 评论(8) 收藏 举报
分类:

快速幂取模


用法:用于求解 a 的 b 次方,而b是一个非常大的数,用O(n)的复杂度会超时。那么就需要这个算法,注意它不但可以对数求次幂,而且可用于矩阵快速幂。


假如求 x ^ n 次方


我们可以把 n 表示为 2^k1 + 2k2  + 2^k3....,可以证明所有数都可以用前式来表示。(其实就是二进制表示数的原理)


那么 x^n = x^2^k1 * x^2^k2 * x^2^k3......


那么就可以利用二进制来加快计算速度了。


假如 x^22 , 22转化为二进制为 10110, 即 x^22 = x^16 * x^4 * x^2;


那么是不是可以在O(logn)的复杂度求解。


代码:


typedef long long LL;
LL fun(LL x,LL n,)
{
    LL res=1;
    while(n>0)
    {
        if(n & 1)
            res=(res*x)%Max;
        x=(x*x)%Max;
        n >>= 1;
    }
    return res;
}


那么假如让你求一个矩阵的很大的次方幂呢,当然我们同样可以求解。


比如我们都知道斐波那契数列可以用矩阵来求



当求第非常大的一个斐波那契数的后几位时我们可以用上面方法求解了。


方法和上面的方法一模一样,只是把数 x 变成了一个矩阵。


注意代码中矩阵的存法,很好用,题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=148


#include <cstdio>
#include <iostream>
#include <vector>

using namespace std;
typedef vector<int> vec;
typedef vector<vec> mat;
typedef long long LL;
const int N = 10000;
mat mul(mat a,mat b)  //矩阵乘法
{
    mat c(a.size(),vec(b[0].size()));
    for(int i=0;i<a.size();i++)
    {
        for(int k=0;k<b.size();k++)
        {
            for(int j=0;j<b[0].size();j++)
                c[i][j] = ( c[i][j] + a[i][k] * b[k][j] ) % N;
        }
    }
    return c;
}

mat solve_pow(mat a,int n) //快速幂
{
    mat b(a.size(),vec(a.size()));
    for(int i=0;i<a.size();i++)
        b[i][i]=1;
    while(n>0)
    {
        if(n & 1)
            b=mul(b,a);
        a=mul(a,a);
        n >>= 1;
    }

    return b;
}
LL n;
void solve()
{
    mat a(2,vec(2));
    while(~scanf("%d",&n) && n!=-1)
    {
        a[0][0]=1,a[0][1]=1;
        a[1][0]=1,a[1][1]=0;
        a=solve_pow(a,n);
        printf("%d\n",a[1][0]);
    }
}
int main()
{
    solve();
    return 0;
}



13
1
查看评论

蓝桥杯 算法训练 矩阵乘方(矩阵快速幂取模)

算法训练 矩阵乘方   时间限制:1.0s   内存限制:512.0MB      问题描述   给定一个矩阵A,一个非负整数b和一个正整数m,求A的b次方除m的余数。   其中一个nxn的矩阵除m的余数得到的仍是一个nxn的矩...
  • Sterben_Da
  • Sterben_Da
  • 2016-01-03 15:57
  • 1109

快速幂取模算法详解

1.大数模幂运算的缺陷: 快速幂取模算法的引入是从大数的小数取模的朴素算法的局限性所提出的,在朴素的方法中我们计算一个数比如5^1003%31是非常消耗我们的计算资源的,在整个计算过程中最麻烦的就是我们的5^1003这个过程 缺点1:在我们在之后计算指数的过程中,计算的数字不都拿得增大,非常的占用我...
  • ltyqljhwcm
  • ltyqljhwcm
  • 2016-11-05 10:40
  • 15128

Code::Blocks 使用技巧.4-编辑内容无级缩放

  • nanyu
  • nanyu
  • 2010-05-18 00:47
  • 4927

快速幂

因为以前吃过很多快速幂的亏,所以这次拿它作为我博客的第一篇文章。首先是简单的一个求n的n次幂再对m取余的程序(c语言)。 #include int main() { int n,i,m,s=1; scanf("%d %d",&n,&m);  ...
  • cswhit
  • cswhit
  • 2016-06-14 22:17
  • 5469

快速幂的简单解释

快速幂算法,顾名思义就是求幂时速度很快(废话 看了很多博客里的解释,都说得很玄奥……其实快速幂很容易解释的。 比如求3的20次幂,一般我们会用循环乘法来求,也就是需要循环20次。
  • kencaber
  • kencaber
  • 2016-08-26 16:00
  • 1127

快速幂学习入门

快速幂学习心得: 1、快速幂大致分为普通的快速幂,快速乘法,矩阵快速幂(point); 2、快速幂主要应用的是二进制,详细的见模板。 3、快速乘法,其实乘法就是多个数相加,当数据很大的时候加起来会非常的慢,这里可以用到快速幂的思想。详细见模板 4、主要的还是矩阵快速幂,矩阵快速幂可以将矩阵看...
  • yopilipala
  • yopilipala
  • 2017-04-02 16:23
  • 960

[转]快速幂(C语言实现) 超详细

快速幂取模算法在网站上一直没有找到有关于快速幂算法的一个详细的描述和解释,这里,我给出快速幂算法的完整解释,用的是C语言,不同语言的读者只好换个位啦,毕竟读C的人较多~所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余)。在程序设计过程中,经常要去求一些大数对于某个数的余...
  • ghui23
  • ghui23
  • 2016-07-21 21:12
  • 775

快速幂(C语言实现) 超详细 (转载)

快速幂取模算法 在网站上一直没有找到有关于快速幂算法的一个详细的描述和解释,这里,我给出快速幂算法的完整解释,用的是C语言,不同语言的读者只好换个位啦,毕竟读C的人较多~ 所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余)。在程序设计过程中,经常要去求一些大数对于某...
  • xuruoxin
  • xuruoxin
  • 2013-02-12 00:50
  • 27344

快速幂

试题         求a^b的后三位数。a,b是整数。         这题也就是计算a^b%1000的值。 解法一         先求出a^b的值,然后计算a^b%m即可。 ...
  • java_c_android
  • java_c_android
  • 2017-02-19 17:23
  • 537

【每日算法】快速幂

数值的整数次方实现函数double Power(double base, int n) 求base的n次方,不得使用库函数,同时不需要考虑大数问题。Tips问题本身很直观,但是越简单的题越需要细心思考,包括边界问题和效率问题,如果不能考虑到以下3点,就无法给出令人满意的答案: 考虑n为负数的情况;...
  • jiange_zh
  • jiange_zh
  • 2016-02-18 11:50
  • 3402
    个人资料
    • 访问:1001060次
    • 积分:11691
    • 等级:
    • 排名:第1545名
    • 原创:323篇
    • 转载:3篇
    • 译文:3篇
    • 评论:183条
    最新评论