【矩阵乘法x2】LuoGu P1349 广义斐波那契数列&&LNSYOJ#395递推式前缀和
这是两道矩阵的水题
题目描述
数列f[n]=f[n-1]+f[n-2]+n+1,f[1]=f[2]=1的前n项和s[n]=f[1]+f[2]+……+f[n]的快速求法(答案取模10e9+7)
输入格式
一个整数bb。
输出格式
一个整数前缀和。
样例一
input
3
output
8
限制与约定
对于50%的数据,1≤n≤1061≤n≤106
对于100%的数据,1≤n≤10121≤n≤1012
时间限制:1s1s
空间限制:256MB256MB
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
题目描述
广义的斐波那契数列是指形如an=p\times a_{n-1}+q\times a_{n-2}an=p×an−1+q×an−2的数列。今给定数列的两系数pp和qq,以及数列的最前两项a_1a1和a_2a2,另给出两个整数nn和mm,试求数列的第nn项a_nan除以mm的余数。
输入输出格式
输入格式:
输入包含一行6个整数。依次是pp,qq,a_1a1,a_2a2,nn,mm,其中在pp,qq,a_1a1,a_2a2整数范围内,nn和mm在长整数范围内。
输出格式:
输出包含一行一个整数,即a_nan除以mm的余数。
输入输出样例
说明
数列第10项是55,除以7的余数为6。
第一个的矩阵就是这个东西
$$\left[ {\matrix
1 & 1 & 1 & 0 & 0 \\
1 & 0 & 1 & 0 & 0 \\
0 & 0 & 1 & 0 & 0 \\
1 & 0 & 1 & 1 & 0 \\
2 & 0 & 2 & 1 & 1 \\
\endmatrix } \right]$$
第二个的更水,就是这个东西
\[\left( {\begin{array}{*{20}{c}}
p&1\\
q&0
\end{array}} \right)\]
然后就A了;
注意细节!!!
1 //first 2 #include<cstdio> 3 #include<cstring> 4 #define mod 1000000007 5 using namespace std; 6 typedef long long lt; 7 lt b; 8 struct matrix 9 { 10 lt a[5][5]; 11 friend matrix operator*(matrix a,matrix b) 12 { 13 matrix fina; 14 memset(&fina,0,sizeof(fina)); 15 for(int i=0;i<5;i++) 16 for(int j=0;j<5;j++) 17 for(int k=0;k<5;k++) 18 fina.a[i][j]=(fina.a[i][j]+a.a[i][k]*b.a[k][j])%mod; 19 return fina; 20 } 21 friend matrix operator^(matrix a,lt k) 22 { 23 matrix fina; 24 memset(&fina,0,sizeof(fina)); 25 fina.a[0][0]=fina.a[1][1]=fina.a[2][2]=fina.a[3][3]=fina.a[4][4]=1; 26 while(k) 27 { 28 if(k%2)fina=fina*a; 29 k>>=1,a=a*a; 30 } 31 return fina; 32 } 33 }key,im; 34 int main() 35 { 36 key.a[0][0]=key.a[0][1]=key.a[0][2]=key.a[1][0]=key.a[1][2]=key.a[2][2] 37 =key.a[3][0]=key.a[3][2]=key.a[3][3]=key.a[4][3]=key.a[4][4]=1; 38 key.a[4][0]=key.a[4][2]=2; 39 im.a[0][0]=im.a[0][1]=im.a[0][4]=1; 40 im.a[0][2]=im.a[0][3]=2; 41 scanf("%lld",&b); 42 key=key^(b-2); 43 im=im*key; 44 printf("%lld",im.a[0][2]); 45 return 0; 46 }
1 //second 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 typedef long long lt; 6 lt p,q,a1,a2,n,m; 7 struct matrix 8 { 9 lt a[2][2]; 10 friend matrix operator*(matrix a,matrix b) 11 { 12 matrix fina; 13 memset(&fina,0,sizeof(fina)); 14 for(int i=0;i<2;i++) 15 for(int j=0;j<2;j++) 16 for(int k=0;k<2;k++) 17 fina.a[i][j]=(fina.a[i][j]+a.a[i][k]*b.a[k][j])%m; 18 return fina; 19 } 20 friend matrix operator^(matrix a,lt k) 21 { 22 matrix fina; 23 memset(&fina,0,sizeof(fina)); 24 fina.a[0][0]=fina.a[1][1]=1; 25 while(k) 26 { 27 if(k%2)fina=fina*a; 28 k>>=1,a=a*a; 29 } 30 return fina; 31 } 32 }key,im; 33 int main() 34 { 35 scanf("%lld%lld%lld%lld%lld%lld",&p,&q,&a1,&a2,&n,&m); 36 key.a[0][0]=p,key.a[1][0]=q,key.a[0][1]=1; 37 im.a[0][0]=a2,im.a[0][1]=a1; 38 key=key^(n-2),im=im*key; 39 printf("%lld",im.a[0][0]%m); 40 return 0; 41 }