1. 程式人生 > >【矩陣乘法x2】LuoGu P1349 廣義斐波那契數列&&LNSYOJ#395遞推式字首和

【矩陣乘法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%的資料1n1061≤n≤106

對於100%的資料

1012">1n10121≤n≤1012

時間限制1s1s

空間限制256MB256MB

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

題目描述

廣義的斐波那契數列是指形如an=p\times a_{n-1}+q\times a_{n-2}an=p×an1+q×an2的數列。今給定數列的兩係數pp和qq,以及數列的最前兩項a_1a1a_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 }