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