Advertisement
dan_sml

Untitled

Jul 15th, 2020
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.73 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define int long long
  3.  
  4. using namespace std;
  5.  
  6. const int INF = 1e9;
  7. int n, m, k;
  8. vector <vector <int>> a;
  9. vector <int> sm;
  10. vector <bool> is_reversed;
  11. vector <int> h, a1, a2;
  12.  
  13. void result() {
  14.     for (int i = 0; i < a.size(); i++) {
  15.         for (int j = 0; j < a[i].size(); j++) cout << a[i][j] << " ";
  16.         cout << "\n";
  17.     }
  18.     cout << "\n";
  19. }
  20.  
  21. void split(int i) {
  22.     h.resize(a[i].size() - k);
  23.     copy(a[i].begin() + k, a[i].end(), h.begin());
  24.     a.insert(a.begin() + i + 1, h);
  25.     sm.insert(sm.begin() + i + 1, 0);
  26.     is_reversed.insert(is_reversed.begin() + i + 1, false);
  27.     for (int j = 0; j < h.size(); j++) {
  28.         sm[i] -= a[i + 1][j];
  29.         sm[i + 1] += a[i + 1][j];
  30.     }
  31.     a[i].resize(k);
  32. }
  33.  
  34. void swap_(int l1, int r1, int i1, int l2, int r2, int i2) {
  35.     a1.resize(l1 + r2 + 1);
  36.     a2.resize(a[i1].size() - l1 + a[i2].size() - r2 - 1);
  37.     copy(a[i1].begin(), a[i1].begin() + l1, a1.begin());
  38.     copy(a[i2].begin(), a[i2].begin() + r2 + 1, a1.begin() + l1);
  39.     copy(a[i1].begin() + l1, a[i1].end(), a2.begin());
  40.     copy(a[i2].begin() + r2 + 1, a[i2].end(), a2.begin() + a[i1].size() - l1);
  41.     swap(a[i1], a1);
  42.     swap(a[i2], a2);
  43.     a1.clear();
  44.     a2.clear();
  45. }
  46.  
  47. int sum(int l, int r, int i) {
  48.     int res = 0;
  49.     for (int j = l; j <= r; j++) res += a[i][j];
  50.     return res;
  51. }
  52.  
  53. void apply(int i) {
  54.     if (is_reversed[i]) reverse(a[i].begin(), a[i].end());
  55.     is_reversed[i] = false;
  56. }
  57.  
  58. void reverse_(int l, int r) {
  59.     int l0 = 0, r0, ft = INF, lt = 0, pos_ft, pos_lt;
  60.     for (int i = 0; i < a.size(); i++) {
  61.         r0 = l0 + a[i].size() - 1;
  62.         if (!(r < l0 || r0 < l)) {
  63.             if (i < ft) {
  64.                 ft = i;
  65.                 pos_ft = l0;
  66.             }
  67.             lt = i;
  68.             pos_lt = l0;
  69.             is_reversed[i] = !is_reversed[i];
  70.         }
  71.         l0 = r0 + 1;
  72.     }
  73.     if (ft - lt == 0) {
  74.         is_reversed[ft] = !is_reversed[ft];
  75.         apply(ft);
  76.         reverse(a[ft].begin() + l - pos_ft, a[ft].begin() + r - pos_ft + 1);
  77.     }
  78.     else {
  79.         is_reversed[ft] = !is_reversed[ft];
  80.         is_reversed[lt] = !is_reversed[lt];
  81.         apply(ft);
  82.         apply(lt);
  83.         int l1 = l - pos_ft, r1 = a[ft].size() - 1;
  84.         int l2 = 0, r2 = r - pos_lt;
  85.         int smft = sum(l1, r1, ft);
  86.         int smlt = sum(l2, r2, lt);
  87.         sm[ft] += smlt - smft;
  88.         sm[lt] += smft - smlt;
  89.         reverse(a[ft].begin() + l1, a[ft].begin() + r1 + 1);
  90.         reverse(a[lt].begin() + l2, a[lt].begin() + r2 + 1);
  91.         swap_(l1, r1, ft, l2, r2, lt);
  92.         if (a[ft].size() >= 2 * k) split(ft);
  93.         if (a[lt].size() >= 2 * k) split(lt);
  94.     }
  95.     if (ft - lt > 3) {
  96.         reverse(a.begin() + ft + 1, a.begin() + lt);
  97.         reverse(sm.begin() + ft + 1, sm.begin() + lt);
  98.     }
  99. }
  100.  
  101. int ans(int l, int r) {
  102.     int l0 = 0, r0, res = 0;
  103.     for (int i = 0; i < a.size(); i++) {
  104.         r0 = l0 + a[i].size() - 1;
  105.         if (l <= l0 && r0 <= r) res += sm[i];
  106.         else if (!(r < l0 || r0 < l)) {
  107.             apply(i);
  108.             res += sum(max(l, l0) - l0, min(r, r0) - l0, i);
  109.         }
  110.         l0 += a[i].size();
  111.     }
  112.     return res;
  113. }
  114.  
  115. signed main() {
  116.     cin >> n >> m;
  117.     k = sqrt(n);
  118.     a.resize((n - 1) / k + 1);
  119.     sm.assign((n - 1) / k + 1, 0);
  120.     is_reversed.assign((n - 1) / k + 1, false);
  121.     for (int i = 0; i < n; i++) {
  122.         int ai;
  123.         cin >> ai;
  124.         a[i / k].push_back(ai);
  125.         sm[i / k] += ai;
  126.     }
  127.     //result();
  128.     for (int _ = 0; _ < m; _++) {
  129.         int type, l, r;
  130.         cin >> type >> l >> r;
  131.         l--;
  132.         r--;
  133.         if (type) reverse_(l, r);
  134.         else cout << ans(l, r) << "\n";
  135.         //result();
  136.     }
  137. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement