题目描述
https://www.luogu.com.cn/problem/P1939
Solution
我们来考虑如何构造矩阵
好了,考虑完了
时间复杂度 $O(9T\log n)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| #include <iostream> #include <cstring> #include <cstdio> #define cM const Matrix using namespace std;
const int p = 1000000007;
inline int add(int x, int y) { return x + y >= p ? x + y - p : x + y; }
int n;
struct Matrix { int a[4][4], n; Matrix() { memset(a, 0, sizeof a); n = 3; } inline void setone() { for (int i = 1; i <= n; ++i) a[i][i] = 1; }
friend Matrix operator * (cM &u, cM &v) { Matrix w; int n = w.n; for (int k = 1; k <= n; ++k) for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) w.a[i][j] = add(w.a[i][j], 1ll * u.a[i][k] * v.a[k][j] % p); return w; } } ;
Matrix pow(Matrix x, int n) { Matrix s; s.setone(); for (; n; n >>= 1) { if (n & 1) s = s * x; x = x * x; } return s; }
void work() { cin >> n; Matrix a, b; a.a[1][1] = a.a[2][1] = a.a[3][1] = 1; b.a[1][1] = b.a[1][3] = b.a[2][1] = b.a[3][2] = 1; if (n <= 3) return (void) puts("1"); printf("%d\n", (pow(b, n - 3) * a).a[1][1]); }
int main() { int T; cin >> T; while (T--) work(); return 0; }
|