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
| template<typename T, int M> struct matrix_t { using row = vector<T>; using mat = vector<row>; using ll = long long; static void mul(const mat& a, const mat& b, mat& c) { auto m = a.size(), p = a[0].size(), n = b[0].size(); for (int i = 0; i < m; ++i) { for (int k = 0; k < p; ++k) { for (int j = 0; j < n; ++j) { c[i][j] = (c[i][j] + (ll)a[i][k] * b[k][j]) % M; } } } } static mat mul(const mat& a, const mat& b) { auto m = a.size(), n = b[0].size(); mat c = vector<row>(m, row(n, 0)); mul(a, b, c); return c; } static mat qpow(mat a, ll k) { auto n = a.size(); mat ans = vector<row>(n, row(n, 0)); for (int i = 0; i < n; ++i) { ans[i][i] = 1; } while (k) { if (k & 1) { ans = mul(a, ans); } k >>= 1; a = mul(a, a); } return ans; } }; const int M = 1e9 + 7; using matrix = matrix_t<int, M>; class Solution { public: int fib(int n) { vector<vector<int>> mat = {{0, 1}, {1, 1}}; vector<vector<int>> vec = {{0, 1}}; mat = matrix::qpow(mat, n); return matrix::mul(vec, mat)[0][0]; } };
|