--- tags: codebook --- {%hackmd theme-dark %} # matrix calculation ## latest ```cpp= #include<iostream> #include<vector> #include<algorithm> #define endl '\n' using namespace std; constexpr int mod = 1e9 + 7; template<int n, int m> struct matrix { vector<vector<int>> data; vector<int>& operator[](size_t x) {return data[x];} const vector<int>& operator[](size_t x) const {return data[x];} matrix(): data(n, vector<int>(m)) {} matrix(initializer_list<initializer_list<int>> x): data(n, vector<int>(m)) { int tmp = 0; for (const auto& i : x) data[tmp++].assign(i); } }; template<int n, int m, int k> matrix<n, m> operator*(const matrix<n, k>& a, const matrix<k, m>& b) { matrix<n, m> ret; for (int i = 0; i != n; i++) for (int j = 0; j != m; j++) for (int l = 0; l != k; l++) ret[i][j] += 1LL * a[i][l] * b[l][j] % mod, ret[i][j] %= mod; return ret; } template<int n> matrix<n, n> unit() { matrix<n, n> ret; for (int i = 0; i != n; i++) ret[i][i] = 1; return ret; } template<int n> matrix<n, n> pow(matrix<n, n> a, long long b) { matrix<n, n> ret = unit<n>(); for (; b; b >>= 1, a = a * a) if (b & 1) ret = ret * a; return ret; } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); matrix<3, 3> trans{ {0, 1, 0}, {0, 0, 1}, {1, 1, 1} }; int n; while (cin >> n) cout << (pow(trans, n - 1) * matrix<3, 1> {{1}, {2}, {4}})[0][0] << endl; return 0; } ``` ## old ver ```cpp= #include<iostream> #include<vector> #include<utility> #include<algorithm> using namespace std; constexpr long long mod = 1e9 + 7; struct matrix { vector<vector<long long>> data; pair<size_t, size_t> size() const {return {data.size(), data.front().size()};} vector<long long>& operator[](const size_t& x) {return data[x];} const vector<long long>& operator[] (const size_t& x)const {return data[x];} void resize(const size_t& a, const size_t& b, const long long& val = 0) { for (auto& i : data) i.resize(b, val); data.resize(a, vector<long long>(b, val)); } void assign(const size_t& a, const size_t& b, const long long& val) { data.assign(a, vector<long long>(b, val)); } matrix(const vector<vector<long long>>&v = {}): data(v) {} matrix(const size_t& a, const size_t& b, const long long& val = 0) { assign(a, b, val); } }; matrix operator*(const matrix& a, const matrix& b) { matrix tmp(vector<vector<long long>>(a.size().first, vector<long long>(b.size().second, 0))); for (size_t i = 0; i != tmp.size().first; i++) { for (size_t j = 0; j != tmp.size().second; j++) { for (size_t k = 0; k != a.size().second; k++) tmp[i][j] += a[i][k] * b[k][j] % mod; tmp[i][j] %= mod; } } return tmp; } matrix operator+(matrix a, const matrix& b) { for (size_t i = 0; i != a.size().first; i++) for (size_t j = 0; j != a.size().second; j++) a[i][j] -= b[i][j]; return a; } matrix operator-(matrix a) { for (auto& i : a.data) for (auto& j : i) j = -j; return a; } matrix operator-(matrix a, const matrix& b) { return a + (-b); } bool operator==(const matrix& a, const matrix& b) { if (a.size() != b.size()) return false; for (size_t i = 0; i != a.size().first; i++) for (size_t j = 0; j != a.size().second; j++) if (a[i][j] != b[i][j]) return false; return true; } bool operator!=(const matrix& a, const matrix& b) { return !(a == b); } matrix operator*=(matrix& a, const matrix& b) { return a = a * b; } matrix operator+=(matrix& a, const matrix& b) { return a = a + b; } matrix operator-=(matrix& a, const matrix& b) { return a = a - b; } matrix pow(matrix a, unsigned long long b) { matrix re(vector<vector<long long>>(a.size().first, vector<long long>(a.size().second, 0))); for (size_t i = 0; i < min(a.size().first, a.size().second); i++) re[i][i] = 1; for (; b; b >>= 1, a = a * a) if (b & 1) re = re * a; return re; } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); vector<vector<long long>> arr{{1, 1}, {1, 0}}; unsigned long long n; matrix fib(arr); while (cin >> n) cout << pow(fib, n + 1)[1][1] << endl; return 0; } ``` ## template ```cpp= template<typename T> struct matrix { vector<vector<T>> data; pair<size_t, size_t> size() const {return {data.size(), data.front().size()};} vector<T>& operator[](const size_t& x) {return data[x];} const vector<T>& operator[] (const size_t& x)const {return data[x];} void resize(const size_t& a, const size_t& b, const T& val = 0) { for (auto& i : data) i.resize(b, val); data.resize(a, vector<T>(b, val)); } void assign(const size_t& a, const size_t& b, const T& val) { data.assign(a, vector<T>(b, val)); } matrix(const vector<vector<T>>&v = {}): data(v) {} matrix(const size_t& a, const size_t& b, const T& val = 0) { assign(a, b, val); } }; template<typename T> matrix<T> operator*(const matrix<T>& a, const matrix<T>& b) { matrix<T> tmp(vector<vector<T>>(a.size().first, vector<T>(b.size().second, 0))); for (size_t i = 0; i != tmp.size().first; i++) { for (size_t j = 0; j != tmp.size().second; j++) { for (size_t k = 0; k != a.size().second; k++) tmp[i][j] += a[i][k] * b[k][j]; tmp[i][j]; } } return tmp; } template<typename T> matrix<T> operator+(matrix<T> a, const matrix<T>& b) { for (size_t i = 0; i != a.size().first; i++) for (size_t j = 0; j != a.size().second; j++) a[i][j] -= b[i][j]; return a; } template<typename T> matrix<T> operator-(matrix<T> a) { for (auto& i : a.data) for (auto& j : i) j = -j; return a; } template<typename T> matrix<T> operator-(matrix<T> a, const matrix<T>& b) { return a + (-b); } template<typename T> bool operator==(const matrix<T>& a, const matrix<T>& b) { if (a.size() != b.size()) return false; for (size_t i = 0; i != a.size().first; i++) for (size_t j = 0; j != a.size().second; j++) if (a[i][j] != b[i][j]) return false; return true; } template<typename T> bool operator!=(const matrix<T>& a, const matrix<T>& b) { return !(a == b); } template<typename T> matrix<T> operator*=(matrix<T>& a, const matrix<T>& b) { return a = a * b; } template<typename T> matrix<T> operator+=(matrix<T>& a, const matrix<T>& b) { return a = a + b; } template<typename T> matrix<T> operator-=(matrix<T>& a, const matrix<T>& b) { return a = a - b; } template<typename T> matrix<T> pow(matrix<T> a, unsigned long long b) { matrix<T> re(vector<vector<T>>(a.size().first, vector<T>(a.size().second, 0))); for (size_t i = 0; i < min(a.size().first, a.size().second); i++) re[i][i] = 1; for (; b; b >>= 1, a = a * a) if (b & 1) re = re * a; return re; } ```