【快速幂】
博客转载快速幂讲解
以下是我自己理解的快速幂(假设是求 ):
我们把 b 看成是 2 进制数,比如说 11 就是 1011,就是
那么
这样乘 11 次就直接降为了乘 3 次
时间复杂度O()
代码(求 ):
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
long long a,b,c,ans,res;
scanf("%lld%lld%lld",&a,&b,&c);
ans=1,res=a;
while(b)
{
if(b&1)
ans=(ans*res)%c;
res=(res*res)%c;
b>>=1;
}
printf("%lld",ans);
return 0;
}
【矩阵快速幂】
博客转载矩阵快速幂讲解
矩阵快速幂实际上和快速幂差不多
只不过是每次乘的时候改成矩阵乘法
下面的 res 和 ans 和上面的也差不多
具体的话我们以快速求斐波那契数列为例吧,例题传送门
.
上面是公式,我们只要只需要用矩阵快速幂就可以快速求解了
其实很多递推式(不只是斐波那契数列)都可以用矩阵快速幂快速求解,主要是推出原始矩阵的值,就比如斐波那契数列是 ,不同的递推式的话就有不同的原始矩阵,推出来就可以很方便地求解了
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 10
#define mod 10000
using namespace std;
struct matrix
{
int m[N][N];
}ans,res;
matrix multiply(matrix a,matrix b)
{
int i,j,k;
matrix temp;
for(i=1;i<=2;++i)
for(j=1;j<=2;++j)
temp.m[i][j]=0;
for(i=1;i<=2;++i)
for(j=1;j<=2;++j)
for(k=1;k<=2;++k)
temp.m[i][j]=(temp.m[i][j]+1ll*a.m[i][k]*b.m[k][j])%mod;
return temp;
}
void quickpower(int x)
{
int i,j;
res.m[1][1]=1;ans.m[1][1]=1;
res.m[1][2]=1;ans.m[1][2]=0;
res.m[2][1]=1;ans.m[2][1]=0;
res.m[2][2]=0;ans.m[2][2]=1;
while(x)
{
if(x&1)
ans=multiply(ans,res);
res=multiply(res,res);
x>>=1;
}
}
int main()
{
int x;
while(~scanf("%d",&x))
{
if(x==-1) break;
quickpower(x);
printf("%d\n",ans.m[1][2]);
}
return 0;
}