题目: 传送门
题意: 已知数列递推公式为
a
n
=
(
3
a
n
−
1
+
4
a
n
−
2
)
m
o
d
1
e
9
+
7
a_n = (3a_{n-1} + 4a_{n-2}) ~mod ~1e9 ~+~7
an=(3an−1+4an−2) mod 1e9 + 7
现在给你a1和a2,要求
a
n
a_n
an
思路:
看如下矩阵乘法:
(
a
n
a
n
−
1
)
=
(
3
4
1
0
)
∗
(
a
n
−
1
a
n
−
2
)
\begin{pmatrix} a_n \\ a_{n-1} \end{pmatrix} = \begin{pmatrix} 3 & 4 \\ 1 & 0 \end{pmatrix} * \begin{pmatrix} a_{n-1} \\ a_{n-2} \end{pmatrix}
(anan−1)=(3140)∗(an−1an−2)
可以一直递推,得到:
(
a
n
a
n
−
1
)
=
(
3
4
1
0
)
n
−
1
∗
(
a
2
a
1
)
\begin{pmatrix} a_n \\ a_{n-1} \end{pmatrix} = \begin{pmatrix} 3 & 4 \\ 1 & 0 \end{pmatrix}^{n-1} * \begin{pmatrix} a_2 \\ a_1 \end{pmatrix}
(anan−1)=(3140)n−1∗(a2a1)
如果
(
3
4
1
0
)
n
−
1
=
(
A
B
C
D
)
\begin{pmatrix} 3 & 4 \\ 1 & 0 \end{pmatrix}^{n-1} = \begin{pmatrix} A & B \\ C & D \end{pmatrix}
(3140)n−1=(ACBD)
那
a
n
a_n
an =
A
∗
a
2
+
B
∗
a
1
A*a_2 + B*a_1
A∗a2+B∗a1
由于n到了1e12,所以用快速幂
Code:
#pragma GCC optimize(2)
#include<iostream>
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
struct matrix {
ll a, b, c, d;
matrix() {}
matrix (ll aa, ll bb, ll cc, ll dd) {
a = aa;
b = bb;
c = cc;
d = dd;
}
matrix operator * (const matrix& x) {
matrix tmp;
tmp.a = a*x.a + b*x.c;
tmp.b = a*x.b + b*x.d;
tmp.c = c*x.a + d*x.c;
tmp.d = c*x.b + d*x.d;
return tmp;
}
matrix operator % (ll k) {
matrix tmp(a%k, b%k, c%k, d%k);
return tmp;
}
};
matrix qpow(matrix a, ll n) {
matrix ans(1,0,0,1);
matrix t = a;
while (n > 0) {
if (n & 1) {
ans = ((ans)%mod * (t%mod)) % mod;
}
t = ((t%mod) * (t%mod)) % mod;
n >>= 1;
}
return ans % mod;
}
int main()
{
ll n, a1, a2;
cin>>n>>a1>>a2;
matrix a(3,4,1,0), c;
c = qpow(a, n - 2);
//cout<<c.a<<" "<<c.b<<endl<<c.c<<" "<<c.d<<endl;
cout<<(c.a * (a2%mod) + c.b * (a1 % mod)) % mod<<endl;
return 0;
}