【矩阵乘法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%的数据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 }

 

posted @ 2018-12-14 18:57  浅夜_MISAKI  阅读(270)  评论(0编辑  收藏  举报