Raslboyy

2789

Oct 13th, 2019
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.95 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <ctime>
  4. #include <random>
  5. #include <tuple>
  6. #include <algorithm>
  7. #include <vector>
  8. #include <climits>
  9.  
  10. using namespace std;
  11.  
  12. ifstream fin("input.txt");
  13. ofstream fout("output.txt");
  14.  
  15. class TreapNode
  16. {
  17. public:
  18.     TreapNode(int val) :
  19.         val(val),
  20.         size(1),
  21.         sum(val),
  22.         prior((rand() << 16) | rand()),
  23.         l(nullptr),
  24.         r(nullptr){}
  25.  
  26.     int get_val() { return val; }
  27.     int get_size() { return size; }
  28.     int get_sum() { return (this == nullptr ? 0 : sum); }
  29.     int get_prior() { return prior; }
  30.     TreapNode* get_l() { relax(); return l; }
  31.     TreapNode* get_r() { relax(); return r; }
  32.     void set_l(TreapNode* l) { this->l = l; relax(); }
  33.     void set_r(TreapNode* r) { this->r = r; relax(); }
  34.  
  35. private:
  36.     int val;
  37.     int size;
  38.     int sum;
  39.     int prior;
  40.     TreapNode* l;
  41.     TreapNode* r;
  42.     void relax();
  43. };
  44.  
  45. void TreapNode::relax() {
  46.     int size_l = (l == nullptr ? 0 : l->get_size());
  47.     int size_r = (r == nullptr ? 0 : r->get_size());
  48.     size = size_l + 1 + size_r;
  49.  
  50.     int sum_l = (l == nullptr ? 0 : l->get_sum());
  51.     int sum_r = (r == nullptr ? 0 : r->get_sum());
  52.     sum = sum_l + val + sum_r;
  53. }
  54.  
  55. class Treap {
  56. public:
  57.     Treap() : even(nullptr), odd(nullptr) {}
  58.     void Add_even(int val) { even = merge(even, new TreapNode(val)); }
  59.     void Add_odd(int val) { odd = merge(odd, new TreapNode(val)); }
  60.     void Swap(int l, int r);
  61.     int Sum(int l, int r);
  62. private:
  63.     TreapNode* even;
  64.     TreapNode* odd;
  65.     TreapNode* merge(TreapNode* t1, TreapNode* t2);
  66.     TreapNode* merge(TreapNode* t1, TreapNode* t2, TreapNode* t3);
  67.     tuple<TreapNode*, TreapNode*> split(TreapNode* t, int x);
  68.     tuple<TreapNode*, TreapNode*, TreapNode*> split(TreapNode* t, int l, int r);
  69. };
  70.  
  71. TreapNode* Treap::merge(TreapNode* t1, TreapNode* t2) {
  72.     if (t1 == nullptr) return t2;
  73.     if (t2 == nullptr) return t1;
  74.     if (t1->get_prior() > t2->get_prior()) {
  75.         t1->set_r(merge(t1->get_r(), t2));
  76.         return t1;
  77.     }
  78.     else {
  79.         t2->set_l(merge(t1, t2->get_l()));
  80.         return t2;
  81.     }
  82. }
  83. TreapNode* Treap::merge(TreapNode* t1, TreapNode* t2, TreapNode* t3) {
  84.     return merge(t1, merge(t2, t3));
  85. }
  86.  
  87. tuple<TreapNode*, TreapNode*> Treap::split(TreapNode* t, int x) {
  88.     if (t == nullptr) return make_tuple(nullptr, nullptr);
  89.     int size_l = (t->get_l() == nullptr ? 0 : t->get_l()->get_size());
  90.     if (x <= size_l) {
  91.         auto sp = split(t->get_l(), x);
  92.         t->set_l(get<1>(sp));
  93.         return make_tuple(get<0>(sp), t);
  94.     }
  95.     else {
  96.         auto sp = split(t->get_r(), x - size_l - 1);
  97.         t->set_r(get<0>(sp));
  98.         return make_tuple(t, get<1>(sp));
  99.     }
  100. }
  101. tuple<TreapNode*, TreapNode*, TreapNode*> Treap::split(TreapNode* t, int l, int r) {
  102.     auto sp1 = split(t, r + 1);
  103.     auto sp2 = split(get<0>(sp1), l);
  104.     return make_tuple(get<0>(sp2), get<1>(sp2), get<1>(sp1));
  105. }
  106.  
  107. int Treap::Sum(int l, int r) {
  108.     if (l > r) return 0;
  109.     int l1 = (l + 1) / 2, r1 = r / 2;
  110.     int l2 = l / 2, r2 = (r + 1) / 2 - 1;
  111.     auto sp_even = split(even, l1, r1);
  112.     auto sp_odd = split(odd, l2, r2);
  113.     int res = get<1>(sp_even)->get_sum() + get<1>(sp_odd)->get_sum();
  114.     merge(get<0>(sp_even), get<1>(sp_even), get<2>(sp_even));
  115.     merge(get<0>(sp_odd), get<1>(sp_odd), get<2>(sp_odd));
  116.     return res;
  117. }
  118.  
  119. void Treap::Swap(int l, int r) {
  120.     int l1 = (l + 1) / 2, r1 = r / 2;
  121.     int l2 = l / 2, r2 = (r + 1) / 2 - 1;
  122.     auto sp_even = split(even, l1, r1);
  123.     auto sp_odd = split(odd, l2, r2);
  124.     even = merge(get<0>(sp_even), get<1>(sp_odd), get<2>(sp_even));
  125.     odd = merge(get<0>(sp_odd), get<1>(sp_even), get<2>(sp_odd));
  126. }
  127.  
  128. int main() {
  129.     srand(time(NULL));
  130.  
  131.     int n, m;
  132.     fin >> n >> m;
  133.     int count = 1;
  134.     while (n + m) {
  135.         fout << "Swapper " << count << ":" << endl;
  136.         Treap tr;
  137.         for (int i = 0; i < n; i++) {
  138.             int a; fin >> a;
  139.             if (i % 2 == 0) tr.Add_even(a);
  140.             else tr.Add_odd(a);
  141.         }
  142.         for (int i = 0; i < m; i++) {
  143.             int a, l, r; fin >> a >> l >> r;
  144.             l--, r--;
  145.             if (a == 1) tr.Swap(l, r);
  146.             else fout << tr.Sum(l, r) << endl;
  147.         }
  148.         fout << endl;
  149.         count++;
  150.         fin >> n >> m;
  151.     }
  152.  
  153.     fin.close();
  154.     fout.close();
  155.     return 0;
  156. }
Advertisement
Add Comment
Please, Sign In to add comment