矩阵快速幂和普通快速幂道理一样,主要用来加速数列的递推,关键在于构造矩阵。
这几个博客的板子挺好
https://www.cnblogs.com/fzl194/p/8877276.html
题目 落谷模板题p1939
https://www.luogu.com.cn/problem/P1939
贴个代码吧,没用重载
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100;
const int mod = 1e9 + 7;
int n;
struct Mat
{
LL a[maxn][maxn]; //一定要用long long存矩阵,否则在过程中会爆掉
Mat()
{
memset(a, 0, sizeof a);
}
inline void build()
{
for (int i = 1; i <= 3; ++i)
a[i][i] = 1;
}
};
Mat mul(Mat x, Mat y)
{
Mat z;
for (int i = 1; i <= 3; ++i)
for (int k = 1; k <= 3; ++k)
for (int j = 1; j <= 3; ++j)
z.a[i][j] = (z.a[i][j] + x.a[i][k] * y.a[k][j] % mod) % mod;
return z;
}
Mat Mat_qpow(Mat a, LL p)
{
Mat res;
res.build();
while (p)
{
if (p & 1)
res = mul(res, a);
a = mul(a, a);
p = p >> 1;
}
return res;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T;
cin >> T;
Mat t;
t.a[1][1] = 1;
t.a[1][3] = 1;
t.a[2][1] = 1;
t.a[3][2] = 1;
while (T--)
{
cin >> n;
Mat ans = Mat_qpow(t, n - 1);
cout << ans.a[1][1] << endl;
}
return 0;
}