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

库函数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;
}

时间: 2024-12-28 23:43:40

快速幂计算(整数快速幂/矩阵快速幂)的相关文章

hdu 1575 求一个矩阵的k次幂 再求迹 (矩阵快速幂模板题)

Problem DescriptionA为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. Input数据的第一行是一个T,表示有T组数据.每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据.接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容. Output对应每组数据,输出Tr(A^k)%9973. Sample Input22 21 00 13 999999991 2 34

算法初步:快速乘,快速幂,矩阵快速幂

原创 by zoe.zhang 在刷题的时候遇到了问题,就是当循环或者递推的次数非常大的情况下获取一定结果,这个时候如果作普通运算,那么很容易就超时了,而且有时候结果也大得超范围了,即使是long long类型的也放不下,然后给了提示说是运用快速幂的思想.所以这里对快速幂做了一点思考和探讨. 1.快速乘,快速幂,矩阵快速幂三者的关系 不管是快速乘,还是快速幂算法,实际上都包含了分解问题的思想在里面,将O(n)的复杂度降到O(lgn).学习的时候,一般学习快速幂算法,再由此推广去解决矩阵快速幂问题

nyoj_148_fibonacci数列(二)_矩阵快速幂

fibonacci数列(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, … An alterna

数论基础——循环节和矩阵快速幂的运用

首先我们来看一道基础题: 题目链接:HDU1005 Number Sequence 题目描述: Number Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 147421    Accepted Submission(s): 35814 Problem Description A number sequence is

HDOJ 4686 Arc of Dream 矩阵快速幂

矩阵快速幂: 根据关系够建矩阵 , 快速幂解决. Arc of Dream Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 2164    Accepted Submission(s): 680 Problem Description An Arc of Dream is a curve defined by following fun

hdu 5451 Best Solver 矩阵循环群+矩阵快速幂

http://acm.hdu.edu.cn/showproblem.php?pid=5451 题意:给定x    求解 思路: 由斐波那契数列的两种表示方法, 之后可以转化为 线性表示 F[n] = F[n-1] + F[n-2] ; 同时可以看出   和 是 一元二次方程的两根, a  = 1, b = -1 又是之后递推式的系数: 同理这里需要构造出两根为 和 ,这时 a = 1, b = –10 得 F[n] = 10F[n-1] – F[n-2]; (当然可以直接打表递推出关系式) 如果

POJ——3070Fibonacci(矩阵快速幂)

Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12329   Accepted: 8748 Description In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequenc

Reading comprehension HDU - 4990 (矩阵快速幂 or 快速幂+等比数列)

for(i=1;i<=n;i++) { if(i&1)ans=(ans*2+1)%m; else ans=ans*2%m; } 给定n,m.让你用O(log(n))以下时间算出ans. 打表,推出 ans[i] = 2^(i-1) + f[i-2] 故 i奇数:ans[i] = 2^(i-1) + 2^(i-3) ... + 1; i偶数:ans[i] = 2^(i-1) + 2^(i-3) ... + 2; 故可以用等比数列求和公式. 公式涉及除法.我也没弄懂为啥不能用逆元,貌似说是啥逆元

HDOJ 4686 Arc of Dream 矩阵高速幂

矩阵高速幂: 依据关系够建矩阵 , 高速幂解决. Arc of Dream Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 2164    Accepted Submission(s): 680 Problem Description An Arc of Dream is a curve defined by following fun

HDU 1575 Tr A(矩阵高速幂)

题目地址:HDU 1575 矩阵高速幂裸题. 初学矩阵高速幂.曾经学过高速幂.今天一看矩阵高速幂,原来其原理是一样的,这就好办多了.都是利用二分的思想不断的乘.仅仅只是把数字变成了矩阵而已. 代码例如以下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #i