快速幂取模系列问题

   快速幂取模问题即求:   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;
}

猜你喜欢

转载自blog.csdn.net/weixin_42702110/article/details/81069947