This documentation is automatically generated by online-judge-tools/verification-helper
#include "matrix/matrix_field.hpp"
#ifndef KK2_MATRIX_MATRIX_FIELD_HPP
#define KK2_MATRIX_MATRIX_FIELD_HPP 1
#include <algorithm>
#include <cassert>
#include <iostream>
#include <optional>
#include <string>
#include <vector>
#include "../type_traits/io.hpp"
namespace kk2 {
/**
* @brief 行列
*
* @tparam Field invメンバが必要
*/
template <class Field> struct MatrixField {
using value_type = Field;
using mat = MatrixField;
int _h, _w;
std::vector<std::vector<Field>> _mat;
MatrixField() : MatrixField(0) {}
MatrixField(int n) : MatrixField(n, n) {}
MatrixField(int h, int w) {
if (h == 0) {
_h = 0;
_w = w;
} else {
_h = h;
_w = w;
_mat.resize(h, std::vector<Field>(w));
}
}
MatrixField(const std::vector<std::vector<Field>> &mat_)
: _h(mat_.size()),
_w(mat_[0].size()),
_mat(mat_) {}
static mat unit(int n) {
mat res(n, n);
for (int i = 0; i < n; i++) res[i][i] = Field(1);
return res;
}
inline int get_h() const { return _h; }
inline int get_w() const { return _w; }
std::vector<Field> &operator[](int i) {
assert(0 <= i && i < _h);
return _mat[i];
}
const std::vector<Field> &operator[](int i) const {
assert(0 <= i && i < _h);
return _mat[i];
}
template <class IStream, is_istream_t<IStream> * = nullptr> mat &input(IStream &is) {
for (int i = 0; i < _h; i++) {
for (int j = 0; j < _w; j++) { is >> _mat[i][j]; }
}
return *this;
}
template <class OStream, is_ostream_t<OStream> * = nullptr> void output(OStream &os) const {
for (int i = 0; i < _h; i++) {
for (int j = 0; j < _w; j++) os << _mat[i][j] << " \n"[j == _w - 1];
}
}
template <class OStream, is_ostream_t<OStream> * = nullptr>
void debug_output(OStream &os) const {
os << "(h, w): " << "(" << _h << ", " << _w << "), [\n";
for (int i = 0; i < _h; i++) {
os << " [ ";
for (int j = 0; j < _w; j++) os << _mat[i][j] << " ";
os << "]\n";
}
os << "]\n";
}
mat &operator+=(const mat &rhs) {
assert(_h == rhs._h);
assert(_w == rhs._w);
for (int i = 0; i < _h; i++) {
for (int j = 0; j < _w; j++) { _mat[i][j] += rhs._mat[i][j]; }
}
return *this;
}
mat &operator-=(const mat &rhs) {
assert(_h == rhs._h);
assert(_w == rhs._w);
for (int i = 0; i < _h; i++) {
for (int j = 0; j < _w; j++) { _mat[i][j] -= rhs._mat[i][j]; }
}
return *this;
}
mat &operator*=(const mat &rhs) {
assert(_w == rhs._h);
std::vector<std::vector<Field>> res(_h, std::vector<Field>(rhs._w, Field()));
for (int i = 0; i < _h; i++) {
for (int k = 0; k < _w; k++) {
for (int j = 0; j < rhs._w; j++) { res[i][j] += _mat[i][k] * rhs._mat[k][j]; }
}
}
_w = rhs._w;
_mat = std::move(res);
return *this;
}
/**
* @brief 掃き出し
* @tparam RREF 行簡約化行列にするかどうか
* @tparam EARLY_TERMINATE フルランクでないことが確定したときに即打ち切るかどうか
* @param wr 列が[0, wr)の範囲だけで掃き出す.指定がないなら全体で掃き出す.
* @return ランクと行列式を返す.
*/
template <bool RREF = true, bool EARLY_TERMINATE = false>
std::pair<int, Field> sweep(int wr = -1) {
if (wr == -1) wr = _w;
int r = 0;
Field det = 1;
for (int i = 0; i < wr; ++i) {
if (r >= _h) break;
int pivot = r;
while (pivot < _h and _mat[pivot][i] == Field(0)) ++pivot;
if (pivot == _h) {
if constexpr (EARLY_TERMINATE) return {-1, Field(0)};
det = 0;
continue;
}
if (r != pivot) {
det = -det;
std::swap(_mat[r], _mat[pivot]);
}
det *= _mat[r][i];
Field inv = _mat[r][i].inv();
for (int j = i; j < wr; ++j) _mat[r][j] *= inv;
for (int j = RREF ? 0 : r + 1; j < _h; ++j) {
if (j == r) continue;
Field a = _mat[j][i];
if (a == Field(0)) continue;
for (int k = i; k < wr; ++k) { _mat[j][k] -= _mat[r][k] * a; }
}
r++;
}
return {r, det};
}
mat &to_upper_Hessenberg() {
assert(_h == _w);
int n = _h;
for (int i = 0; i < n - 1; ++i) {
int pivot = i + 1;
while (pivot < n and _mat[pivot][i] == Field(0)) ++pivot;
if (pivot == n) continue;
if (pivot != i + 1) {
std::swap(_mat[pivot], _mat[i + 1]);
for (int j = 0; j < n; ++j) std::swap(_mat[j][i + 1], _mat[j][pivot]);
}
if (_mat[i + 1][i] != Field(1)) {
Field a = _mat[i + 1][i], iv = a.inv();
for (int j = i; j < n; ++j) _mat[i + 1][j] *= iv;
for (int j = 0; j < n; ++j) _mat[j][i + 1] *= a;
}
for (int j = i + 2; j < n; ++j) {
Field a = _mat[j][i];
if (a == Field(0)) continue;
for (int k = i; k < n; ++k) _mat[j][k] -= _mat[i + 1][k] * a;
for (int k = 0; k < n; ++k) _mat[k][i + 1] += _mat[k][j] * a;
}
}
return *this;
}
Field det() const {
assert(_h == _w);
return mat(*this).sweep<false, true>().second;
}
std::optional<mat> inv() const {
assert(_h == _w);
int n = _h;
mat res(*this);
res.inplace_combine_right(mat::unit(n));
int r = res.sweep<true, true>().first;
if (r != n) return std::nullopt;
for (int i = 0; i < n; i++) res._mat[i].erase(res[i].begin(), res[i].begin() + n);
res._w = n;
return res;
}
int rank() const { return mat(*this).sweep<false, false>().first; }
mat &shrink() {
while (_h and _mat.back() == std::vector<Field>(_w, Field())) _mat.pop_back(), _h--;
return *this;
}
template <class T> mat pow(T n) const {
assert(_h == _w);
assert(n >= 0);
mat mul(_mat), res = mat::unit(_h);
while (n) {
if (n & 1) res *= mul;
if (n >>= 1) mul *= mul;
}
return res;
}
std::optional<mat> solve(const mat &b) const {
assert(_h == b._h);
assert(b._w == 1);
mat ab = combine_right(b);
int r = ab.sweep<true, false>().first;
if ([&]() {
if (!r) return false;
for (int i = 0; i < _w; i++)
if (ab[r - 1][i] != Field()) return false;
return true;
}()) {
return std::nullopt;
}
mat res(1 + _w - r, _w);
std::vector<int> idx(_w, -1), step(r, -1);
for (int i = 0, j = 0, now = 0; j < _w; j++) {
if (i == r or ab[i][j] == Field(0)) idx[j] = now, res[1 + now++][j] = 1;
else res[0][j] = ab[i].back(), step[i++] = j;
}
for (int i = 0; i < r; i++) {
for (int j = 0; j < _w; j++) {
if (idx[j] != -1) res[idx[j] + 1][step[i]] = -ab[i][j];
}
}
return res;
}
mat &inplace_combine_top(const mat &rhs) {
assert(_w == rhs._w);
_mat.insert(_mat.begin(), rhs._mat.begin(), rhs._mat.end());
_h += rhs._h;
return *this;
}
mat &inplace_combine_bottom(const mat &rhs) {
assert(_w == rhs._w);
_mat.insert(_mat.end(), rhs._mat.begin(), rhs._mat.end());
_h += rhs._h;
return *this;
}
mat &inplace_combine_left(const mat &rhs) {
assert(_h == rhs._h);
for (int i = 0; i < _h; i++) _mat[i].insert(_mat[i].begin(), rhs[i].begin(), rhs[i].end());
_w += rhs._w;
return *this;
}
mat &inplace_combine_right(const mat &rhs) {
assert(_h == rhs._h);
for (int i = 0; i < _h; i++) _mat[i].insert(_mat[i].end(), rhs[i].begin(), rhs[i].end());
_w += rhs._w;
return *this;
}
mat transpose() const {
mat res(_w, _h);
for (int i = 0; i < _h; i++) {
for (int j = 0; j < _w; j++) { res[j][i] = _mat[i][j]; }
}
return res;
}
mat combine_top(const mat &rhs) const { return mat(*this).inplace_combine_top(rhs); }
mat combine_bottom(const mat &rhs) const { return mat(*this).inplace_combine_bottom(rhs); }
mat combine_left(const mat &rhs) const { return mat(*this).inplace_combine_left(rhs); }
mat combine_right(const mat &rhs) const { return mat(*this).inplace_combine_right(rhs); }
mat &inplace_transpose() { return *this = transpose(); }
friend mat operator+(const mat &lhs, const mat &rhs) { return mat(lhs) += rhs; }
friend mat operator-(const mat &lhs, const mat &rhs) { return mat(lhs) -= rhs; }
friend mat operator*(const mat &lhs, const mat &rhs) { return mat(lhs) *= rhs; }
friend bool operator==(const mat &lhs, const mat &rhs) { return lhs._mat == rhs._mat; }
friend bool operator!=(const mat &lhs, const mat &rhs) { return lhs._mat != rhs._mat; }
};
} // namespace kk2
#endif // KK2_MATRIX_MATRIX_FIELD_HPP
Traceback (most recent call last):
File "/opt/hostedtoolcache/Python/3.12.0/x64/lib/python3.12/site-packages/onlinejudge_verify/documentation/build.py", line 71, in _render_source_code_stat
bundled_code = language.bundle(stat.path, basedir=basedir, options={'include_paths': [basedir]}).decode()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/hostedtoolcache/Python/3.12.0/x64/lib/python3.12/site-packages/onlinejudge_verify/languages/cplusplus.py", line 187, in bundle
bundler.update(path)
File "/opt/hostedtoolcache/Python/3.12.0/x64/lib/python3.12/site-packages/onlinejudge_verify/languages/cplusplus_bundle.py", line 401, in update
self.update(self._resolve(pathlib.Path(included), included_from=path))
File "/opt/hostedtoolcache/Python/3.12.0/x64/lib/python3.12/site-packages/onlinejudge_verify/languages/cplusplus_bundle.py", line 312, in update
raise BundleErrorAt(path, i + 1, "#pragma once found in a non-first line")
onlinejudge_verify.languages.cplusplus_bundle.BundleErrorAt: type_traits/io.hpp: line 4: #pragma once found in a non-first line