Advertisement
igoryanchik

Tree

Dec 4th, 2023 (edited)
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.44 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4.  
  5. using namespace std;
  6. using ll = long long;
  7.  
  8. template <class T>
  9. class SegmentTree
  10. {
  11. private:
  12.  
  13.     struct Node
  14.     {
  15.         T modify;
  16.         T query;
  17.     };
  18.  
  19.     int size;
  20.     T q_neutral;
  21.     T m_neutral;
  22.     T(*query)(const T&, const T&);
  23.     T(*modify)(const T&, const T&);
  24.     vector<Node> tree;
  25.  
  26.     void build(const vector<T>& a, int v, int left, int right)
  27.     {
  28.         if (left + 1 == right)
  29.             tree[v].query = a[left];
  30.         else
  31.         {
  32.             int mid = (left + right) >> 1;
  33.             build(a, 2 * v, left, mid);
  34.             build(a, 2 * v + 1, mid, right);
  35.             tree[v].query = query(tree[2 * v].query, tree[2 * v + 1].query);
  36.         }
  37.     }
  38.  
  39.     void propagate(int v, int left, int right)
  40.     {
  41.         if (left + 1 == right || tree[v].modify == m_neutral) return;
  42.  
  43.         tree[2 * v].modify = modify(tree[2 * v].modify, tree[v].modify);
  44.         tree[2 * v].query = modify(tree[2 * v].query, tree[v].modify);
  45.         tree[2 * v + 1].modify = modify(tree[2 * v + 1].modify, tree[v].modify);
  46.         tree[2 * v + 1].query = modify(tree[2 * v + 1].query, tree[v].modify);
  47.  
  48.         tree[v].modify = m_neutral;
  49.     }
  50.  
  51.  
  52.     T getQuery(int v, int start, int end, int left, int right)
  53.     {
  54.         propagate(v, left, right);
  55.         if (end <= left || right <= start)
  56.             return q_neutral;
  57.         if (start <= left && right <= end)
  58.             return tree[v].query;
  59.         else
  60.         {
  61.             int mid = (left + right) >> 1;
  62.             return query(getQuery(2 * v, start, end, left, mid),
  63.                 getQuery(2 * v + 1, start, end, mid, right));
  64.         }
  65.     }
  66.  
  67.     void update(int v, const T& x, int start, int end, int left, int right)
  68.     {
  69.         propagate(v, left, right);
  70.         if (end <= left || right <= start)
  71.             return;
  72.         if (start <= left && right <= end)
  73.         {
  74.             tree[v].modify = modify(tree[v].modify, x);
  75.             tree[v].query = modify(tree[v].query, x);
  76.             return;
  77.         }
  78.         else
  79.         {
  80.             int mid = (left + right) >> 1;
  81.             update(2 * v, x, start, end, left, mid);
  82.             update(2 * v + 1, x, start, end, mid, right);
  83.             tree[v].query = query(tree[2 * v].query, tree[2 * v + 1].query);
  84.         }
  85.  
  86.     }
  87.  
  88.     void get_init_vec_help(vector<T>& vec, int v, int left, int right)
  89.     {
  90.         if (left + 1 == right)
  91.             vec[left] = tree[v].query;
  92.         else
  93.         {
  94.             int mid = (left + right) >> 1;
  95.  
  96.             get_init_vec_help(vec, 2 * v, left, mid);
  97.             get_init_vec_help(vec, 2 * v + 1, mid, right);
  98.         }
  99.     }
  100.  
  101. public:
  102.  
  103.     SegmentTree(int n, T(*_query)(const T&, const T&), T(*_modify)(const T&, const T&), const T& _q_neutral = T(), const T& _m_neutral = T())
  104.         : size(n)
  105.         , q_neutral(_q_neutral)
  106.         , m_neutral(_m_neutral)
  107.         , query(_query)
  108.         , modify(_modify)
  109.         , tree(size << 2, { m_neutral , q_neutral })
  110.     { }
  111.  
  112.     SegmentTree(const vector<T>& vec, T(*_query)(const T&, const T&), T(*_modify)(const T&, const T&), const T& _q_neutral = T(), const T& _m_neutral = T())
  113.         : SegmentTree(vec.size(), _query, _modify, _q_neutral, _m_neutral)
  114.     {
  115.         build(vec, 1, 0, size);
  116.     }
  117.  
  118.     SegmentTree<T> operator =(const SegmentTree<T>& Tree)
  119.     {
  120.         if (this == &Tree) return *this;
  121.  
  122.         size = Tree.size;
  123.         tree = Tree.tree;
  124.         q_neutral = Tree.q_neutral;
  125.         m_neutral = Tree.m_neutral;
  126.         modify = Tree.modify;
  127.         query = Tree.query;
  128.  
  129.         return *this;
  130.     }
  131.  
  132.     SegmentTree<T> merge(SegmentTree<T>& Tree)
  133.     {
  134.         if (q_neutral != Tree.q_neutral || m_neutral != Tree.m_neutral) return *this;
  135.         Tree.propagate(1, 0, Tree.size);
  136.         propagate(1, 0, size);
  137.  
  138.         vector<T> init_vec = get_init_vec();
  139.         vector<T> Tree_init_vec = Tree.get_init_vec();
  140.  
  141.         init_vec.insert(init_vec.end(), Tree_init_vec.begin(), Tree_init_vec.end());
  142.         SegmentTree<T> rez(init_vec, query, modify, q_neutral, m_neutral);
  143.  
  144.         return rez;
  145.     }
  146.  
  147.  
  148.     SegmentTree<T> merge(const SegmentTree<T>& Tree)
  149.     {
  150.         if (q_neutral != Tree.q_neutral || m_neutral != Tree.m_neutral) return *this;
  151.        
  152.         Tree.propagate(1, 0, size);
  153.         propagate(1, 0, size);
  154.  
  155.         int len = max(size, Tree.size) - min(size, Tree.size);
  156.         vector<T> sup_vec(len, 0);
  157.         SegmentTree<T> sup_tree(sup_vec, query, modify, q_neutral, m_neutral);
  158.  
  159.  
  160.  
  161.     }
  162.  
  163.  
  164.     void update(int start, int end, const T& x)
  165.     {
  166.         update(1, x, start, end + 1, 0, size);
  167.     }
  168.  
  169.     const T& getQuery(int start, int end)
  170.     {
  171.         return getQuery(1, start, end + 1, 0, size);
  172.     }
  173.  
  174.     vector<T> get_init_vec()
  175.     {
  176.         vector<T> result(size, 0);
  177.         get_init_vec_help(result, 1, 0, size);
  178.  
  179.         return result;
  180.     }
  181.  
  182.     template <class T>
  183.     friend ostream& operator << (ostream& out, const SegmentTree<T>& Tree);
  184. };
  185.  
  186. template <class T>
  187. ostream& operator << (ostream& out, const SegmentTree<T>& Tree)
  188. {
  189.     if (out)
  190.     {
  191.         for (auto it : Tree.tree)
  192.         {
  193.             cout << it.query << " " << it.modify << '\n';  
  194.         }
  195.     }
  196.  
  197.     return out;
  198. }
  199.  
  200. template <class T>
  201. T modify(const T& a, const T& b)
  202. {
  203.     if (b == 1) return a;
  204.     return b;
  205. }
  206.  
  207. template <class T>
  208. T query(const T& a, const T& b)
  209. {
  210.     return min(a,b);
  211. }
  212.  
  213.  
  214. int main()
  215. {
  216.     vector<ll> vec = { 2,3,4,1,5,6 };
  217.     vector<ll> vec2 = { 2,11,4,5,20 };
  218.  
  219.     ll(*ptr_modify)(const ll&, const ll&) = &modify;
  220.     ll(*ptr_query)(const ll&, const ll&) = &query;
  221.  
  222.     SegmentTree<ll> tree(vec, ptr_query, ptr_modify, LLONG_MAX, 1);
  223.     SegmentTree<ll> tree2(vec2, ptr_query, ptr_modify, LLONG_MAX, 1);
  224.  
  225.  
  226.     cout << tree.getQuery(0, 5) << '\n';
  227.     tree.update(0, 5, 2);
  228.     cout << tree.getQuery(0, 5) << '\n';
  229.     tree.update(0, 5, 2);
  230.     cout << tree.getQuery(0, 5) << '\n';
  231.    
  232.  
  233.     vector<ll> init = tree.get_init_vec();
  234.  
  235.     /*cout << '\n';
  236.     for (ll it : vec)
  237.         cout << it << " ";
  238.  
  239.     cout << '\n' << tree;*/
  240.     //cout << tree2.getQuery(0, 5) << '\n';
  241.  
  242.     //SegmentTree<ll> merge_tree = tree.merge(tree2);
  243.  
  244.  
  245.     return 0;
  246. }
  247.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement