【矩陣乘法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%的資料,
時間限制: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的餘數。
輸入輸出樣例
輸入樣例#1: 複製1 1 1 1 10 7
輸出樣例#1: 複製
6
說明
數列第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 }