Advertisement
Guest User

Segment tree

a guest
Nov 14th, 2019
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.85 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <cstring>
  5. #include <algorithm>
  6. #include <fstream>
  7. #include <iomanip>
  8. #include <iterator>
  9. #include <sstream>
  10. #include <set>
  11. #include <map>
  12. #include <unordered_map>
  13. #include <unordered_set>
  14. #include <list>
  15. #include <ctime>
  16. #include <queue>
  17. #include <cmath>
  18. #include <stack>
  19. #include <functional>
  20. #include <memory>
  21. #include <tuple>
  22. #include <utility>
  23.  
  24. using namespace std;
  25.  
  26. #define __int64 long long
  27. const double pi = atan2(0.0, -1.0);
  28.  
  29. struct dat
  30. {
  31.     __int64 el;
  32.  
  33.     //-----   Изменения   --------
  34.     __int64 change_add = 0; //Прибавка
  35.     bool dead_end = false; //Проверка на лист
  36.  
  37.     friend ostream& operator<<(ostream& is, const dat& l);
  38. };
  39.  
  40. ostream& operator<<(ostream& is, const dat& l)
  41. {
  42.     is << l.el << " ";
  43.     return is;
  44. }
  45.  
  46. struct DO
  47. {
  48.  
  49. private:
  50.     vector<dat> mas; //Само дерево
  51.     vector<__int64> v; //Исходный
  52.     int l, r, n, x;
  53.     function<dat(dat, dat)> fun;//Операция
  54.  
  55. public:
  56.     void create(vector<__int64>& _v, function<dat(dat, dat)> _fun)
  57.     {
  58.         v = _v;
  59.         fun = _fun;
  60.         n = v.size()-1;
  61.         mas.resize(4 * n+8);
  62.         create_rec(1, 0, n);
  63.     }
  64.  
  65.     void update_add(int _l, int _r, int _x)
  66.     {
  67.         l = _l; r = _r; x = _x;
  68.         get(l, r);
  69.         update_add_rec(1, 0, n);
  70.     }
  71.  
  72.     dat get(int _l, int _r)
  73.     {
  74.         l = _l; r = _r;
  75.         return get_rec(1, 0, n);
  76.     }
  77.  
  78. private:
  79.     void create_rec(int ii, int l, int r)
  80.     {
  81.         if (l == r)
  82.         {
  83.             mas[ii].el = v[l];
  84.             mas[ii].dead_end = true;
  85.         }
  86.         else
  87.         {
  88.             int m = (r - l) / 2 + l;
  89.             create_rec(2 * ii, l, m);
  90.             create_rec(2 * ii + 1, m + 1, r);
  91.             mas[ii].el = fun(mas[2 * ii], mas[2 * ii + 1]).el;
  92.         }
  93.     }
  94.      
  95.     void update_add_rec(int ii, int ll, int rr)
  96.     {
  97.  
  98.         if ((ll > r) || (rr < l)) return;
  99.         if ((l <= ll) && (rr <= r))
  100.         {
  101.             mas[ii].el += x * (rr - ll + 1);//Прибавить элемент
  102.             mas[ii].change_add+= x;
  103.             return;
  104.         }
  105.  
  106.         int tm = (rr - ll) / 2 + ll;
  107.         update_add_rec(ii * 2, ll, tm);
  108.         update_add_rec(ii * 2 + 1, tm + 1, rr);
  109.         mas[ii].el = fun(mas[ii * 2], mas[ii * 2 + 1]).el;
  110.  
  111.  
  112.     }
  113.  
  114.     dat get_rec(int ii, int ll, int rr)
  115.     {
  116.         if ((l<=ll) && (rr<=r))
  117.         {
  118.             return mas[ii];
  119.         }
  120.          
  121.         int tm = (rr - ll) / 2 + ll;
  122.         dat buf;
  123.  
  124.         //Проталкиваем изменения
  125.         if (mas[ii].change_add)
  126.         {
  127.             if (!mas[ii].dead_end)
  128.             {
  129.                 mas[ii * 2].el += mas[ii].change_add * (tm - ll + 1);
  130.                 mas[ii * 2 + 1].el += mas[ii].change_add * (rr - tm);
  131.                 mas[ii * 2].change_add += mas[ii].change_add;
  132.                 mas[ii * 2 + 1].change_add += mas[ii].change_add;
  133.             }
  134.             mas[ii].change_add = 0;
  135.         }
  136.          
  137.         //---------
  138.  
  139.         if (tm >= l) buf = get_rec(ii * 2, ll, tm);
  140.         else return get_rec(ii * 2+1, tm+1, rr);
  141.  
  142.         if (tm < r) return fun(buf, get_rec(ii * 2 + 1, tm + 1, rr));
  143.         else return buf;
  144.      
  145.     }
  146.  
  147. };
  148.  
  149. class Global // For zeroing fields in unit test
  150. {
  151. public:
  152.     DO d;
  153.     void solve()
  154.     {
  155.         int n, l ,r, x; cin >> n;
  156.         vector<__int64> v(n);
  157.         for (auto& it : v) cin >> it;
  158.         d.create
  159.         (v,
  160.             [](dat l, dat r)
  161.             {
  162.                 dat re;
  163.                 re.el = l.el + r.el;
  164.                 return re;
  165.             }
  166.         );
  167.         cin >> n;
  168.         char ch;
  169.         for (; n--;)
  170.         {
  171.             cin >> ch;
  172.             switch (ch)
  173.             {
  174.             case 'g':
  175.                 cin >> l;
  176.                 cout<<d.get(l-1, l-1);
  177.                 break;
  178.             case 'a':
  179.                 cin >> l >> r >> x;
  180.                 d.update_add(l - 1, r - 1, x);
  181.             default:
  182.                 break;
  183.             }
  184.              
  185.              
  186.         }
  187.  
  188.     } //Конец
  189.  
  190.     void head()
  191.     {
  192.         int t = 1;
  193.         for (; t--;)
  194.         {
  195.             solve();
  196.         }
  197.     }
  198.  
  199. };
  200.  
  201.  
  202. int main()
  203. {
  204.     // srand(time(0));
  205.     ios_base::sync_with_stdio(0);
  206.     cin.tie(0);
  207.  
  208. #ifdef RED
  209.     freopen("input.txt", "r", stdin);
  210.     freopen("output.txt", "w", stdout);
  211.  
  212.     int amount_TEST = 1;
  213.     cin >> amount_TEST;
  214.     for (int amount_test = 1; amount_test <= amount_TEST; ++amount_test)
  215.     {
  216. #endif
  217.         vector<Global> global;
  218.         global.clear();
  219.         global.resize(1);
  220.         global[0].head();
  221.  
  222. #ifdef RED
  223.         cout << "\nКонец " << amount_test << " Теста\n";
  224.     }
  225. #endif
  226. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement