快速幂与矩阵快速幂学习笔记
今天刷51nod的时候写到了https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1242的斐波那契数列问题,发现我竟然已经忘掉了快速幂模版(QAQ)于是复习了一下:
快速幂就贴一下模版吧
int poww(int a,int b){ int ans=1,base=a; while(b!=0){ if(b&1!=0) ans*=base; base*=base; b>>=1; } return ans; }
这个模版就是求a^b所用的快速幂模版,具体数据根据题目修改。
然后就是矩阵快速幂了,矩阵快速幂相比普通快速幂运算将数的幂变成了矩阵幂,一般模版是这样的
jz cf(jz x,jz y) { jz neww; neww.a[0][0]=0; neww.a[0][1]=0; neww.a[1][0]=0; neww.a[1][1]=0; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) for(int k=0; k<2; k++) { neww.a[i][j]+=x.a[i][k]*y.a[k][j]; neww.a[i][j]%=mod; } } return neww; }
于快速幂相对应,把乘法的幺元1改成单位矩阵,模拟两矩阵相乘的过程。
我看到这里的时候是一脸懵逼的,这跟斐波那契数列有啥关系啊。。
然后我在网上找到了公式。。。
然后就惊了。果然线代要好好学啊(QWQ)
最后返回值的左下角或右上角的数值就是答案了~~记得取模
总代码:
#include<iostream> using namespace std; #define mod 1000000009 struct jz { long long a[2][2]; }; jz bz; jz cf(jz x,jz y) { jz neww; neww.a[0][0]=0; neww.a[0][1]=0; neww.a[1][0]=0; neww.a[1][1]=0; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) for(int k=0; k<2; k++) { neww.a[i][j]+=x.a[i][k]*y.a[k][j]; neww.a[i][j]%=mod; } } return neww; } jz poww(long long b) { jz ans; ans.a[0][0]=1; ans.a[1][1]=1; ans.a[1][0]=0; ans.a[0][1]=0; while(b!=0) { if(b&1!=0) ans=cf(ans,bz); bz=cf(bz,bz); b>>=1; } return ans; } int main() { long long s; cin>>s; bz.a[0][0]=1; bz.a[0][1]=1; bz.a[1][0]=1; bz.a[1][1]=0; jz aaa; aaa=poww(s); cout<<aaa.a[0][1]<<endl; }