本文写于2017-11-09,其中的一些思路和基础知识可能存在问题,公式也未用LATEX编写。本文移至此处时暂未重新学习。
求递推数列的第N项,通常做法的复杂度大概是O(n)
使用矩阵加速幂可以把复杂度降到O(log n)
大体遇到的问题:
- 递推数列化为矩阵
- 矩阵乘法
第一个问题,大概是这样的:
第二个问题就是矩阵乘法啦!
~~
//对于f[n]=∑a[i]*f[n-i]#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;struct sq{long long a[105][105];}base,mu,ans;void init(sq &_1){memset(_1.a,0,sizeof(_1.a));}int m,n;//m 公式中i取值的最大值(即f[n]与f[n-1]~f[n-m-1]直接相关) n 所求的f[n]long long mod;sq mul(sq _1,sq _2)//两个m*m的矩阵相乘{sq ans;init(ans);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)for(int k=1;k<=n;k++)ans.a[i][j]+=_1.a[i][k]*_2.a[k][j]%mod,ans.a[i][j]%=mod;return ans;}sq spow(sq _1,long long k){sq base=_1,ans=_1;k--;while(k){if(k&1) ans=mul(ans,base);base=mul(base,base);k>>=1;}return ans;}sq amul(sq _1,sq _2){sq ans;init(ans);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)ans.a[1][i]+=_1.a[j][1]*_2.a[j][i]%mod,ans.a[1][i]%=mod;return ans;}void build_sq(){init(base);for(int i=1;i<=m;i++) cin>>base.a[1][i];//读入f[n-i]的系数a[i]for(int j=1;j<m;j++) base.a[j+1][j]=1; //把base矩阵建好for(int i=1;i<=m;i++) cin>>mu.a[m-i+1][1];//读入f[1]~f[m]}int main(){ios::sync_with_stdio(false);cin>>m>>n>>mod;build_sq();//把矩阵存好!sq ans=amul(mu,spow(base,n-m));cout<<ans.a[1][1]<<endl;return 0;}
这个代码没有对应任何题,所以不知道对不对
