Matrix Monoid
(monoid/matrix.hpp)
- View this file on GitHub
- Last update: 2026-07-21 20:17:47+09:00
- Include:
#include "monoid/matrix.hpp"
Overview
A monoid for range matrix multiplication. The underlying value_type is an N x N std::array. This is extremely useful for Dynamic DP, where state transitions can be represented as matrix multiplications over a segment tree.
Merging two matrices takes $O(N^3)$ time, so $N$ should be small (typically $N \le 4$).
Example
#include "ds/segtree/segtree.hpp"
#include "monoid/matrix.hpp"
#include <iostream>
#include <vector>
// 2x2 Matrix with long long
using Mat = m1une::monoid::Matrix<long long, 2>;
int main() {
int N = 3;
std::vector<Mat::value_type> init_data(N);
// Initialize matrices (e.g., Fibonacci transition matrices)
for (int i = 0; i < N; ++i) {
init_data[i][0] = {1, 1};
init_data[i][1] = {1, 0};
}
m1une::ds::Segtree<Mat> seg(init_data);
auto res = seg.prod(0, N);
std::cout << res[0][0] << " " << res[0][1] << "\n";
std::cout << res[1][0] << " " << res[1][1] << "\n";
return 0;
}
Interface and Complexity
This is a stateless algebra tag. Generic data structures use its public
value_type, id(), and op(a, b) members. If the type also provides helpers
such as make(...) or inv(x), they are described above or in the documented
properties.
Each static operation runs in the cost of the underlying operation shown in the
properties. Scalar monoids are $O(1)$; monoids whose value_type stores several
items, permutations, or matrices scale with that stored size.
Verified with
Code
#ifndef M1UNE_MONOID_MATRIX_HPP
#define M1UNE_MONOID_MATRIX_HPP 1
#include <array>
namespace m1une {
namespace monoid {
// Monoid for fixed-size square matrix multiplication.
template <typename T, int N>
struct Matrix {
using value_type = std::array<std::array<T, N>, N>;
static constexpr bool commutative = false;
// The identity element is the identity matrix.
static constexpr value_type id() {
value_type res{};
for (int i = 0; i < N; ++i) {
res[i][i] = T(1);
}
return res;
}
// Multiplies two matrices: a * b
static constexpr value_type op(const value_type& a, const value_type& b) {
value_type res{};
for (int i = 0; i < N; ++i) {
for (int k = 0; k < N; ++k) {
for (int j = 0; j < N; ++j) {
res[i][j] += a[i][k] * b[k][j];
}
}
}
return res;
}
};
} // namespace monoid
} // namespace m1une
#endif // M1UNE_MONOID_MATRIX_HPP#line 1 "monoid/matrix.hpp"
#include <array>
namespace m1une {
namespace monoid {
// Monoid for fixed-size square matrix multiplication.
template <typename T, int N>
struct Matrix {
using value_type = std::array<std::array<T, N>, N>;
static constexpr bool commutative = false;
// The identity element is the identity matrix.
static constexpr value_type id() {
value_type res{};
for (int i = 0; i < N; ++i) {
res[i][i] = T(1);
}
return res;
}
// Multiplies two matrices: a * b
static constexpr value_type op(const value_type& a, const value_type& b) {
value_type res{};
for (int i = 0; i < N; ++i) {
for (int k = 0; k < N; ++k) {
for (int j = 0; j < N; ++j) {
res[i][j] += a[i][k] * b[k][j];
}
}
}
return res;
}
};
} // namespace monoid
} // namespace m1une