Advertisement
igoryanchik

Segtree with merge

Oct 30th, 2023 (edited)
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.00 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <numeric>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <complex>
  7. #include <functional>
  8. using namespace std;
  9. using ll = long long;
  10.  
  11. template <class T>
  12. class SegmentTree
  13. {
  14. private:
  15.  
  16.     struct Node
  17.     {
  18.         T modify;
  19.         T query;
  20.     };
  21.  
  22.     int size;
  23.     T q_neutral;
  24.     T m_neutral;
  25.     T(*query)(T, T);
  26.     T(*modify)(T, T);
  27.     vector<Node> tree;
  28.     vector<T> init_vec;
  29.  
  30.     void build(const vector<T>& a, int v, int left, int right)
  31.     {
  32.         if (left + 1 == right)
  33.             tree[v].query = a[left];
  34.         else
  35.         {
  36.             int mid = (left + right) >> 1;
  37.             build(a, 2 * v, left, mid);
  38.             build(a, 2 * v + 1, mid, right);
  39.             tree[v].query = query(tree[2 * v].query, tree[2 * v + 1].query);
  40.         }
  41.     }
  42.  
  43.     void propagate(int v, int left, int right)
  44.     {
  45.         if (left + 1 == right || tree[v].modify == m_neutral) return;
  46.  
  47.         tree[2 * v].modify = modify(tree[2 * v].modify, tree[v].modify);
  48.         tree[2 * v].query = modify(tree[2 * v].query, tree[v].modify);
  49.         tree[2 * v + 1].modify = modify(tree[2 * v + 1].modify, tree[v].modify);
  50.         tree[2 * v + 1].query = modify(tree[2 * v + 1].query, tree[v].modify);
  51.  
  52.         tree[v].modify = m_neutral;
  53.     }
  54.  
  55.     T getQuery(int v, int start, int end, int left, int right)
  56.     {
  57.         propagate(v, left, right);
  58.         if (end <= left || right <= start)
  59.             return q_neutral;
  60.         if (start <= left && right <= end)
  61.             return tree[v].query;
  62.         else
  63.         {
  64.             int mid = (left + right) >> 1;
  65.             return query(getQuery(2 * v, start, end, left, mid),
  66.                 getQuery(2 * v + 1, start, end, mid, right));
  67.         }
  68.     }
  69.  
  70.     void update(int v, const T& x, int start, int end, int left, int right)
  71.     {
  72.         propagate(v, left, right);
  73.         if (end <= left || right <= start)
  74.             return;
  75.         if (start <= left && right <= end)
  76.         {
  77.             tree[v].modify = modify(tree[v].modify, x);
  78.             propagate(v, left, right);
  79.             return;
  80.         }
  81.         else
  82.         {
  83.             int mid = (left + right) >> 1;
  84.             update(2 * v, x, start, end, left, mid);
  85.             update(2 * v, x, start, end, mid, right);
  86.             tree[v].query = query(tree[2 * v].query, tree[2 * v + 1].query);
  87.         }
  88.  
  89.     }
  90.  
  91. public:
  92.  
  93.     SegmentTree(int n, T(*_query)(T, T), T(*_modify)(T, T), const T& _q_neutral = T(), const T& _m_neutral = T())
  94.         : size(n)
  95.         , q_neutral(_q_neutral)
  96.         , m_neutral(_m_neutral)
  97.         , query(_query)
  98.         , modify(_modify)
  99.         , tree(size << 2, { m_neutral , q_neutral })
  100.     { }
  101.  
  102.     SegmentTree(vector<T>& vec, T(*_query)(T, T), T(*_modify)(T, T), const T& _q_neutral = T(), const T& _m_neutral = T())
  103.         : SegmentTree(vec.size(), _query, _modify, _q_neutral, _m_neutral)
  104.     {
  105.         init_vec = vec;
  106.         build(vec, 1, 0, size);
  107.     }
  108.  
  109.     SegmentTree<T> operator =(const SegmentTree<T>& Tree)
  110.     {
  111.         if (this == &Tree) return *this;
  112.  
  113.         size = Tree.size;
  114.         tree = Tree.tree;
  115.         q_neutral = Tree.q_neutral;
  116.         m_neutral = Tree.m_neutral;
  117.         modify = Tree.modify;
  118.         query = Tree.query;
  119.         init_vec = Tree.init_vec;
  120.  
  121.         return *this;
  122.     }
  123.  
  124.     SegmentTree<T> merge(SegmentTree<T>& Tree)
  125.     {
  126.         Tree.propagate(1, 0, Tree.size);
  127.         propagate(1, 0, size);
  128.  
  129.         vector<T> new_vec(size + Tree.size);
  130.  
  131.         for (int i = 0; i < size; ++i)
  132.             new_vec[i] = init_vec[i];
  133.  
  134.         for (int i = 0; i < Tree.size; ++i)
  135.             new_vec[size + i] = Tree.init_vec[i];
  136.  
  137.         SegmentTree<T> new_tree(new_vec, query, modify, q_neutral, m_neutral);
  138.  
  139.         return new_tree;
  140.     }
  141.    
  142.     void update(int start, int end, const T& x)
  143.     {
  144.         update(1, x, start, end + 1, 0, size);
  145.     }
  146.  
  147.     T getQuery(int start, int end)
  148.     {
  149.         return getQuery(1, start, end, 0, size);
  150.     }
  151.  
  152. };
  153.  
  154. ll query(ll a, ll b)
  155. {
  156.     return min(a, b);
  157. }
  158.  
  159. ll modify(ll a, ll b)
  160. {
  161.     return a + b;
  162. }
  163.  
  164.  
  165. int main()
  166. {
  167.     vector<ll> vec = { 1,2,3,4,5 };
  168.     vector<ll> vec2 = { 0,6,7,8,9 };
  169.     ll(*modigy_ptr)(ll, ll) = &modify;
  170.     ll(*query_ptr)(ll, ll) = &query;
  171.  
  172.     SegmentTree<ll> tree(vec, modigy_ptr, modigy_ptr, 0, 0);
  173.     SegmentTree<ll> tree2(vec2, modigy_ptr, modigy_ptr, 0, 0);
  174.  
  175.     cout << tree.getQuery(0, 5) << '\n';
  176.     cout << tree2.getQuery(0, 5) << '\n';
  177.  
  178.  
  179.     SegmentTree<ll> merge_tree = tree.merge(tree2);
  180.     cout << merge_tree.getQuery(0, 10) << '\n';
  181.  
  182.  
  183.    
  184.  
  185.     return 0;
  186. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement