快速幂取模系列问题

本文详细介绍了快速幂算法及其在求解a^b%c问题中的应用,同时提供了循环和递归两种实现方式。此外,还介绍了如何使用快速乘法避免数据溢出,并深入探讨了矩阵快速幂在处理递推式时的高效解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   快速幂取模问题即求:   a^b%c

   如果直接用暴力求解,要考虑时间复杂度,溢出的情况,所以要采用快速幂来求解。

  用快速幂求解,首先要知道两个公式:

               1.(a*b)mod c=[(a mod c)*(b mod c)]mod c

               2.(a^b) mod c=[a mod c]^b mod c

     注: 求   a^b%c  时,要考虑b的奇偶性

   快速幂的代码如下:

            1.循环            时间复杂度为logn

long long pow(long long a,long long b,long long c)
{
    a=a%c;
    long long ans=1;
    while(b>0)
    {
        if(b&1)  ans=(ans*a)%c;  //b为奇数
        a=(a*a)%c;
        b/=2;   //b>>=1;
    }
    return ans;
}

         2.递归     时间复杂度为logn

long long pow(long long a,long long b,long long c)
{
    if(b==0) return 1;
    int x=pow(a,b/2,c);
    long long ans=(long long )x*x%c;
    if(b&1) ans=ans*a%c;
    return ans;
}

  有时候,在算ans时,数据有可能会爆掉,ans=ans*a%c,其实就是一个乘法 a*b,即a个b相加,这时候用快速乘法算,就不会爆掉。快速乘法的思想和快速幂是一样的,只需要把“ * ”改为“ + ”,代码如下:

long long Plus(long long a,long long b,long long c)
{
    long long ans=0;
    while(b>0)
    {
        if(b&1)  ans=(ans+a)%c;
        a=(a+a)%c;
        b/=2;
    } 
    return ans;
}

除此之外,涉及矩阵时,还有矩阵快速幂,矩阵快速幂只适用于方阵。

矩阵快速幂一般用在获得一个递推式后,通过矩阵构造来求得某一个函数值。此时的矩阵往往要经过n次或n-1次幂才可以算出答案。例如:           F(n) = a*F(n-1)+b*F(n-2)+c

      构造得      【F(n),F(n-1),1】=【F(n-1),F(n-2),1】【a  1  0

                                                                                       b  0  0

                                                                                      c   0   1】

           要算F(n)只要算出矩阵得n-2次幂,再与[F(2),F(1),1]相乘。

矩阵快速幂得代码:

#include <iostream>
#define N 10
using namespace std;
int Mod;
struct Matrix
{
    int a[N][N];
    void Init()
    {
        for(int i=0;i<N;i++)
        {
            a[i][i]=1;            //矩阵单位化
        }
    }
};
Matrix multi(Matrix a,Matrix b)
{
    Matrix c;
    c.Init();
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<N;j++)
        {
            c.a[i][j]=0;
            for(int k=0;k<N;k++)
            {
                c.a[i][j]+=a.a[i][k]*b.a[k][j];
                c.a[i][j]%=Mod;
            }
        }
    }
    return c;
}
Matrix quick(Matrix a,int k)
{
    Matrix b;
    b.Init();
    while(b>0)
    {
        if(b&1) b=multi(b,a);
        a=multi(a,a);
        b/=2;
    }
    return b;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值