This documentation is automatically generated by online-judge-tools/verification-helper
#include "structure/segment-tree/persistent-segment-tree.hpp"
セグメント木のある要素に対して何らかの更新を行うとする. ここで更新後のセグメント木をすべてコピーして残しておくことが永続であるが, これを単純に実装すると, $1$ 回のコピーに $O(N)$ かかってこわれてしまう. $1$ 回の更新によって $O(\log N)$ 個のノードの情報しか変化しないので, 変化したノードの情報だけ新しくノードを生成してその部分のみ張り替えるする操作を行えば $O(\log N)$ でのコピーが可能になり, これは一般のセグメント木の計算量と変わらない.
PersistentSegmentTree(f, M1)
: f
は2つの区間の要素をマージする二項演算, M1
はモノイドの単位元である.build(v)
: 配列 v
を各要素としたセグメント木を構築し, その根を返す.update(t, k, x)
: t
を根とするセグメント木に対し k
番目の要素を x
に更新し, 更新後の根を返す.query(t, a, b)
: t
を根とするセグメント木に対し, 区間 $[a, b)$ の要素を二項演算した結果を返す.build(v)
: $O(N)$/**
* @brief Persistent-Segment-Tree(永続セグメント木)
*
*/
template< typename Monoid >
struct PersistentSegmentTree {
using F = function< Monoid(Monoid, Monoid) >;
struct Node {
Monoid data;
Node *l, *r;
Node(const Monoid &data) : data(data), l(nullptr), r(nullptr) {}
};
int sz;
const F f;
const Monoid M1;
PersistentSegmentTree(const F f, const Monoid &M1) : f(f), M1(M1) {}
Node *build(vector< Monoid > &v) {
sz = (int) v.size();
return build(0, (int) v.size(), v);
}
Node *merge(Node *l, Node *r) {
auto t = new Node(f(l->data, r->data));
t->l = l;
t->r = r;
return t;
}
Node *build(int l, int r, vector< Monoid > &v) {
if(l + 1 >= r) return new Node(v[l]);
return merge(build(l, (l + r) >> 1, v), build((l + r) >> 1, r, v));
}
Node *update(int a, const Monoid &x, Node *k, int l, int r) {
if(r <= a || a + 1 <= l) {
return k;
} else if(a <= l && r <= a + 1) {
return new Node(x);
} else {
return merge(update(a, x, k->l, l, (l + r) >> 1), update(a, x, k->r, (l + r) >> 1, r));
}
}
Node *update(Node *t, int k, const Monoid &x) {
return update(k, x, t, 0, sz);
}
Monoid query(int a, int b, Node *k, int l, int r) {
if(r <= a || b <= l) {
return M1;
} else if(a <= l && r <= b) {
return k->data;
} else {
return f(query(a, b, k->l, l, (l + r) >> 1),
query(a, b, k->r, (l + r) >> 1, r));
}
}
Monoid query(Node *t, int a, int b) {
return query(a, b, t, 0, sz);
}
};
#line 1 "structure/segment-tree/persistent-segment-tree.hpp"
/**
* @brief Persistent-Segment-Tree(永続セグメント木)
*
*/
template< typename Monoid >
struct PersistentSegmentTree {
using F = function< Monoid(Monoid, Monoid) >;
struct Node {
Monoid data;
Node *l, *r;
Node(const Monoid &data) : data(data), l(nullptr), r(nullptr) {}
};
int sz;
const F f;
const Monoid M1;
PersistentSegmentTree(const F f, const Monoid &M1) : f(f), M1(M1) {}
Node *build(vector< Monoid > &v) {
sz = (int) v.size();
return build(0, (int) v.size(), v);
}
Node *merge(Node *l, Node *r) {
auto t = new Node(f(l->data, r->data));
t->l = l;
t->r = r;
return t;
}
Node *build(int l, int r, vector< Monoid > &v) {
if(l + 1 >= r) return new Node(v[l]);
return merge(build(l, (l + r) >> 1, v), build((l + r) >> 1, r, v));
}
Node *update(int a, const Monoid &x, Node *k, int l, int r) {
if(r <= a || a + 1 <= l) {
return k;
} else if(a <= l && r <= a + 1) {
return new Node(x);
} else {
return merge(update(a, x, k->l, l, (l + r) >> 1), update(a, x, k->r, (l + r) >> 1, r));
}
}
Node *update(Node *t, int k, const Monoid &x) {
return update(k, x, t, 0, sz);
}
Monoid query(int a, int b, Node *k, int l, int r) {
if(r <= a || b <= l) {
return M1;
} else if(a <= l && r <= b) {
return k->data;
} else {
return f(query(a, b, k->l, l, (l + r) >> 1),
query(a, b, k->r, (l + r) >> 1, r));
}
}
Monoid query(Node *t, int a, int b) {
return query(a, b, t, 0, sz);
}
};