码迷,mamicode.com
首页 > 其他好文 > 详细

快速幂计算(整数快速幂/矩阵快速幂)

时间:2016-09-20 19:39:52      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

库函数pow是用朴素算法对浮点型数据进行幂运算的,时间复杂度为o(n),计算比较大的数可能会超时和数据溢出;

 

//*************快速幂计算****************************************

 

朴素算法实现:

ll get_pow(ll x, ll n)  //** (这里的n要求不小于0,如果n小于0则令n=-n,并且最终返回1.0/ans即可)
{
    ll ans=1;
    while(n--)
    {
        ans*=x%MAX;
        ans%=MAX;
    }
    return ans;
}

 

快速幂算法:

原理:

二分:

假设我们现在要计算pow(x,n),那么有当n为偶数时pow(x, n)==pow(x*x, n/2),当n为奇数时,pow(x, n)==pow(x, n-1)*x, 此时n-1为偶数,可按前面的公式继续迭代;

循环往复,即可计算出答案;

 

二进制:

计算pow(x,n),先将n转化为二进制形式,n=2^a+2^b....

例如:计算pow(x,21),19=2^4+2^2+2^1;其中2^2可以由(2^1)*(2^1)得到,同理, 2^4可以由(2^2)*(2^2)得到;

所有有pow(x,21)==x^(2^4+2^2+2^1),其时间复杂度为o(long2(n));

 

以上两种思路的出发点不同,不过其本质一致,代码也相同;

 

代码:

ll get_pow(ll x, ll n)  //** (这里的n要求不小于0,如果n小于0则令n=-n,并且最终返回1.0/ans即可)
{
    int ans=1;
    while(n)
    {
        if(n&1)
        {
            ans=(ans*x)%MAX;
        }
        x=(x*x)%MAX;
        n>>=1;
    }
    return ans;
}

 

//*********************矩阵快速幂计算**********************************

矩阵快速幂和快速幂算法原理一样,只是操作对象换成了矩阵;

http://acm.nyist.net/JudgeOnline/problem.php?pid=148(题目链接)

 

ac代码:

#include <bits/stdc++.h>
#define MAXN 2
#define mod 10000
#define ll long long
using namespace std;

struct Matrix
{
    ll x[MAXN][MAXN];
};

Matrix temp={1, 1, 1, 0};

ll n;  //***n为幂数,结果对mod取模

Matrix multi(Matrix a, Matrix b) //***矩阵乘法
{
    Matrix c;
    memset(c.x, 0, sizeof(c.x));
    for(int i=0; i<MAXN; i++)
    {
        for(int j=0; j<MAXN; j++)
        {
            for(int k=0; k<MAXN; k++)
            {
                c.x[i][j]+=(a.x[i][k]*b.x[k][j])%mod;
            }
        }
    }
    return c;
}

ll Pow(ll n)
{
    Matrix ans;
    temp.x[0][0]=temp.x[0][1]=temp.x[1][0]=1;
    temp.x[1][1]=0;
    memset(ans.x, 0, sizeof(ans.x));
    ans.x[0][0]=ans.x[1][1]=1;
    while(n)
    {
        if(n&1) ans=multi(ans, temp);
        temp=multi(temp, temp);
        n>>=1;
    }
    return ans.x[0][1];
}

int main(void)
{
    std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    while(cin >> n && n!=-1)
    {
        cout << Pow(n)%mod << endl;
    }
    return 0;
}

 

快速幂计算(整数快速幂/矩阵快速幂)

标签:

原文地址:http://www.cnblogs.com/geloutingyu/p/5889950.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!