【洛谷】P1349广义斐波那契
题目链接:https://www.luogu.org/problemnew/show/P1349
题意:现在定义fib数列为 an = p * an-1 + q * an-2求第n项%m的答案。
题解:
\begin{pmatrix} p & 1\\ q & 0 \end{pmatrix} *
\begin{pmatrix} f(n-1)& f(n-2) \end{pmatrix} =
\begin{pmatrix} p*f(n-1) + q*f(n-2)& f(n-1) \end{pmatrix}=
\begin{pmatrix} f(n)& f(n-1) \end{pmatrix}
这题有个玄学mod。矩阵乘法的时候记得要多mod一次。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 #define ll long long 6 const int maxn = 3; 7 8 ll n,mod; 9 10 //矩阵结构体 11 struct Matrix{ 12 ll a[maxn][maxn]; 13 void init(){ //初始化为单位矩阵 14 memset(a, 0, sizeof(a)); 15 for(int i = 1; i <= maxn;i++){ 16 a[i][i] = 1; 17 } 18 } 19 }; 20 21 //矩阵乘法 22 Matrix mul(Matrix a, Matrix b){ 23 Matrix ans; 24 for(int i = 1;i <= 2;++i){ 25 for(int j = 1;j <= 2;++j){ 26 ans.a[i][j] = 0; 27 for(int k = 1;k <= 2;++k){ 28 ans.a[i][j] = ans.a[i][j] % mod + a.a[i][k] * b.a[k][j] % mod; 29 ans.a[i][j] %= mod; 30 } 31 } 32 } 33 return ans; 34 } 35 36 //矩阵快速幂 37 Matrix qpow(Matrix a,ll b){ 38 Matrix ans; 39 ans.init(); 40 while(b){ 41 if(b & 1) 42 ans = mul(ans,a); 43 a = mul(a,a); 44 b >>= 1; 45 } 46 return ans; 47 } 48 49 void print(Matrix a){ 50 for(int i = 1; i <= n;++i){ 51 for(int j = 1;j <= n;++j){ 52 cout << a.a[i][j]%mod<< " "; 53 } 54 cout << endl; 55 } 56 } 57 58 int main(){ 59 ll p,q,a1,a2; 60 cin>>p>>q>>a1>>a2>>n>>mod; 61 if(n == 1){ 62 cout<<a1%mod<<endl; 63 return 0; 64 } 65 if(n == 2){ 66 cout<<a2%mod<<endl; 67 return 0; 68 } 69 Matrix base; 70 Matrix ans; 71 ans.a[1][1] = a2;ans.a[1][2] = a1; 72 73 base.a[1][1] = p;base.a[1][2] = 1; 74 base.a[2][1] = q;base.a[2][2] = 0; 75 76 ans = mul(ans,qpow(base,n-2)); 77 //print(ans); 78 cout<<ans.a[1][1]%mod<<endl; 79 return 0; 80 }