C++ アルゴリズムとデータ構造のライブラリ
#include "library/segtree/segment_tree.hpp"set: $O(logN)$prod: $O(logN)$SegmentTree<int> seg(Monoid::Min::op, Monoid::Min::e, N);
#pragma once
#include <functional>
#include "library/various/monoid.hpp"
template <typename T> struct SegmentTree {
using F = function<T(T, T)>;
private:
F op;
T e;
int N, size, log = 1;
vector<T> node;
void init() {
while ((1ll << log) < N) ++log;
node.assign((size = 1ll << log) << 1, e);
}
public:
SegmentTree(F op, T e, int N) : op(op), e(e), N(N) { init(); }
SegmentTree(F op, T e, const vector<T> &A) : op(op), e(e), N(A.size()) {
init();
for (int i = 0; i < N; ++i) node[i + size] = A[i];
for (int i = size - 1; i >= 1; --i)
node[i] = op(node[i << 1 | 0], node[i << 1 | 1]);
}
void set(int i, const T &x) {
node[i += size] = x;
while (i >>= 1) node[i] = op(node[i << 1 | 0], node[i << 1 | 1]);
}
T prod(int l, int r) {
T L = e, R = e;
for (l += size, r += size; l < r; l >>= 1, r >>= 1) {
if (l & 1) L = op(L, node[l++]);
if (r & 1) R = op(node[--r], R);
}
return op(L, R);
}
};#line 2 "library/segtree/segment_tree.hpp"
#include <functional>
#line 2 "library/various/monoid.hpp"
/**
* @brief モノイド
*/
struct Monoid {
// 最小値
struct Min {
static constexpr int e = INT_MAX;
static int op(int x, int y) { return min(x, y); }
};
// 最大値
struct Max {
static constexpr int e = -INT_MAX;
static int op(int x, int y) { return max(x, y); }
};
// 加算
struct Add {
static constexpr int e = 0;
static int op(int x, int y) { return x + y; }
};
// 乗算
struct Mul {
static constexpr int e = 1;
static int op(int x, int y) { return x * y; }
};
// 代入
struct Set {
static constexpr int e = INT_MAX;
static int op(int x, int y) { return y == INT_MAX ? x : y; }
};
// 最大公約数
struct Gcd {
static constexpr int e = 0;
static int op(int x, int y) { return gcd(x, y); }
};
// 最小公倍数
struct Lcm {
static constexpr int e = 1;
static int op(int x, int y) { return lcm(x, y); }
};
// 排他的論理和
struct Xor {
static constexpr int e = 0;
static int op(int x, int y) { return x ^ y; }
};
};
#line 4 "library/segtree/segment_tree.hpp"
template <typename T> struct SegmentTree {
using F = function<T(T, T)>;
private:
F op;
T e;
int N, size, log = 1;
vector<T> node;
void init() {
while ((1ll << log) < N) ++log;
node.assign((size = 1ll << log) << 1, e);
}
public:
SegmentTree(F op, T e, int N) : op(op), e(e), N(N) { init(); }
SegmentTree(F op, T e, const vector<T> &A) : op(op), e(e), N(A.size()) {
init();
for (int i = 0; i < N; ++i) node[i + size] = A[i];
for (int i = size - 1; i >= 1; --i)
node[i] = op(node[i << 1 | 0], node[i << 1 | 1]);
}
void set(int i, const T &x) {
node[i += size] = x;
while (i >>= 1) node[i] = op(node[i << 1 | 0], node[i << 1 | 1]);
}
T prod(int l, int r) {
T L = e, R = e;
for (l += size, r += size; l < r; l >>= 1, r >>= 1) {
if (l & 1) L = op(L, node[l++]);
if (r & 1) R = op(node[--r], R);
}
return op(L, R);
}
};