This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub dnx04/algo
#include "math/matrix.hpp"
template <typename T> struct matrix { int n_row, n_col; vector<T> x; // accessors typename vector<T>::iterator operator[](int r) { return x.begin() + r * n_col; } inline T get(int i, int j) const { return x[i * n_col + j]; } // constructors matrix() = default; matrix(int n_row, int n_col, T val = 0) : n_row(n_row), n_col(n_col), x(n_row * n_col, val) {} matrix(const vector<vector<T>>& d) : n_row(d.size()), n_col(d.size() ? d[0].size() : 0) { for (auto& row : d) copy(row.begin(), row.end(), back_inserter(x)); } // convert to 2d vec vector<vector<T>> vecvec() const { vector<vector<T>> ret(n_row); for (int i = 0; i < n_row; i++) { copy(x.begin() + i * n_col, x.begin() + (i + 1) * n_col, back_inserter(ret[i])); } return ret; } operator vector<vector<T>>() const { return vecvec(); } static matrix identity(int n) { matrix res(n, n); for (int i = 0; i < n; i++) { res[i][i] = 1; } return res; } matrix transpose() const { matrix res(n_col, n_row); for (int i = 0; i < n_row; i++) { for (int j = 0; j < n_col; j++) { res[j][i] = this->get(i, j); } } return res; } matrix& operator*=(const matrix& r) { return *this = *this * r; } matrix operator*(const matrix& r) const { assert(n_col == r.n_row); matrix res(n_row, r.n_col); for (int i = 0; i < n_row; i++) { for (int k = 0; k < n_col; k++) { for (int j = 0; j < r.n_col; j++) { res[i][j] += this->get(i, k) * r.get(k, j); } } } return res; } matrix operator^(long long n) const { assert(n_row == n_col); if (n == 0) return identity(n_row); if (n == 1) return *this; matrix res = *this ^ (n >> 1); res = res * res; if (n & 1) res = res * *this; return res; } };
#line 1 "math/matrix.hpp" template <typename T> struct matrix { int n_row, n_col; vector<T> x; // accessors typename vector<T>::iterator operator[](int r) { return x.begin() + r * n_col; } inline T get(int i, int j) const { return x[i * n_col + j]; } // constructors matrix() = default; matrix(int n_row, int n_col, T val = 0) : n_row(n_row), n_col(n_col), x(n_row * n_col, val) {} matrix(const vector<vector<T>>& d) : n_row(d.size()), n_col(d.size() ? d[0].size() : 0) { for (auto& row : d) copy(row.begin(), row.end(), back_inserter(x)); } // convert to 2d vec vector<vector<T>> vecvec() const { vector<vector<T>> ret(n_row); for (int i = 0; i < n_row; i++) { copy(x.begin() + i * n_col, x.begin() + (i + 1) * n_col, back_inserter(ret[i])); } return ret; } operator vector<vector<T>>() const { return vecvec(); } static matrix identity(int n) { matrix res(n, n); for (int i = 0; i < n; i++) { res[i][i] = 1; } return res; } matrix transpose() const { matrix res(n_col, n_row); for (int i = 0; i < n_row; i++) { for (int j = 0; j < n_col; j++) { res[j][i] = this->get(i, j); } } return res; } matrix& operator*=(const matrix& r) { return *this = *this * r; } matrix operator*(const matrix& r) const { assert(n_col == r.n_row); matrix res(n_row, r.n_col); for (int i = 0; i < n_row; i++) { for (int k = 0; k < n_col; k++) { for (int j = 0; j < r.n_col; j++) { res[i][j] += this->get(i, k) * r.get(k, j); } } } return res; } matrix operator^(long long n) const { assert(n_row == n_col); if (n == 0) return identity(n_row); if (n == 1) return *this; matrix res = *this ^ (n >> 1); res = res * res; if (n & 1) res = res * *this; return res; } };