Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <numeric>
- #include <cmath>
- #include <algorithm>
- #include <complex>
- #include <functional>
- using namespace std;
- using ll = long long;
- template <class T>
- class SegmentTree
- {
- private:
- struct Node
- {
- T modify;
- T query;
- };
- int size;
- T q_neutral;
- T m_neutral;
- T(*query)(T, T);
- T(*modify)(T, T);
- vector<Node> tree;
- vector<T> init_vec;
- void build(const vector<T>& a, int v, int left, int right)
- {
- if (left + 1 == right)
- tree[v].query = a[left];
- else
- {
- int mid = (left + right) >> 1;
- build(a, 2 * v, left, mid);
- build(a, 2 * v + 1, mid, right);
- tree[v].query = query(tree[2 * v].query, tree[2 * v + 1].query);
- }
- }
- void propagate(int v, int left, int right)
- {
- if (left + 1 == right || tree[v].modify == m_neutral) return;
- tree[2 * v].modify = modify(tree[2 * v].modify, tree[v].modify);
- tree[2 * v].query = modify(tree[2 * v].query, tree[v].modify);
- tree[2 * v + 1].modify = modify(tree[2 * v + 1].modify, tree[v].modify);
- tree[2 * v + 1].query = modify(tree[2 * v + 1].query, tree[v].modify);
- tree[v].modify = m_neutral;
- }
- T getQuery(int v, int start, int end, int left, int right)
- {
- propagate(v, left, right);
- if (end <= left || right <= start)
- return q_neutral;
- if (start <= left && right <= end)
- return tree[v].query;
- else
- {
- int mid = (left + right) >> 1;
- return query(getQuery(2 * v, start, end, left, mid),
- getQuery(2 * v + 1, start, end, mid, right));
- }
- }
- void update(int v, const T& x, int start, int end, int left, int right)
- {
- propagate(v, left, right);
- if (end <= left || right <= start)
- return;
- if (start <= left && right <= end)
- {
- tree[v].modify = modify(tree[v].modify, x);
- propagate(v, left, right);
- return;
- }
- else
- {
- int mid = (left + right) >> 1;
- update(2 * v, x, start, end, left, mid);
- update(2 * v, x, start, end, mid, right);
- tree[v].query = query(tree[2 * v].query, tree[2 * v + 1].query);
- }
- }
- public:
- SegmentTree(int n, T(*_query)(T, T), T(*_modify)(T, T), const T& _q_neutral = T(), const T& _m_neutral = T())
- : size(n)
- , q_neutral(_q_neutral)
- , m_neutral(_m_neutral)
- , query(_query)
- , modify(_modify)
- , tree(size << 2, { m_neutral , q_neutral })
- { }
- SegmentTree(vector<T>& vec, T(*_query)(T, T), T(*_modify)(T, T), const T& _q_neutral = T(), const T& _m_neutral = T())
- : SegmentTree(vec.size(), _query, _modify, _q_neutral, _m_neutral)
- {
- init_vec = vec;
- build(vec, 1, 0, size);
- }
- SegmentTree<T> operator =(const SegmentTree<T>& Tree)
- {
- if (this == &Tree) return *this;
- size = Tree.size;
- tree = Tree.tree;
- q_neutral = Tree.q_neutral;
- m_neutral = Tree.m_neutral;
- modify = Tree.modify;
- query = Tree.query;
- init_vec = Tree.init_vec;
- return *this;
- }
- SegmentTree<T> merge(SegmentTree<T>& Tree)
- {
- Tree.propagate(1, 0, Tree.size);
- propagate(1, 0, size);
- vector<T> new_vec(size + Tree.size);
- for (int i = 0; i < size; ++i)
- new_vec[i] = init_vec[i];
- for (int i = 0; i < Tree.size; ++i)
- new_vec[size + i] = Tree.init_vec[i];
- SegmentTree<T> new_tree(new_vec, query, modify, q_neutral, m_neutral);
- return new_tree;
- }
- void update(int start, int end, const T& x)
- {
- update(1, x, start, end + 1, 0, size);
- }
- T getQuery(int start, int end)
- {
- return getQuery(1, start, end, 0, size);
- }
- };
- ll query(ll a, ll b)
- {
- return min(a, b);
- }
- ll modify(ll a, ll b)
- {
- return a + b;
- }
- int main()
- {
- vector<ll> vec = { 1,2,3,4,5 };
- vector<ll> vec2 = { 0,6,7,8,9 };
- ll(*modigy_ptr)(ll, ll) = &modify;
- ll(*query_ptr)(ll, ll) = &query;
- SegmentTree<ll> tree(vec, modigy_ptr, modigy_ptr, 0, 0);
- SegmentTree<ll> tree2(vec2, modigy_ptr, modigy_ptr, 0, 0);
- cout << tree.getQuery(0, 5) << '\n';
- cout << tree2.getQuery(0, 5) << '\n';
- SegmentTree<ll> merge_tree = tree.merge(tree2);
- cout << merge_tree.getQuery(0, 10) << '\n';
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement