Advertisement
Guest User

8466.cpp

a guest
Feb 27th, 2019
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.29 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const int maxn = 100005, maxq = 20005, step = 500, maxb = step * 2 + 5;
  6. const long long inf = 1e18;
  7. int n, q;
  8. long long a[maxn];
  9. int type[maxq], l[maxq], r[maxq], x[maxq];
  10.  
  11. int order[maxn];
  12. int id[maxn], block_start[maxb], sz[maxb];
  13. long long _min[maxb], _max[maxb], offset[maxb], sum[maxb];
  14. int cnt_min[maxb], cnt_max[maxb];
  15.  
  16. void change(long long a, int block) {
  17.     if (a < _min[block]) _min[block] = a, cnt_min[block] = 1;
  18.     else if (a == _min[block]) ++cnt_min[block];
  19.     if (a > _max[block]) _max[block] = a, cnt_max[block] = 1;
  20.     else if (a == _max[block]) ++cnt_max[block];
  21. }
  22.  
  23. long long get_sum(int block) {
  24.     if (_max[block] - _min[block] > 1) return sum[block] + offset[block] * sz[block];
  25.     if (_max[block] - _min[block] == 1) return _min[block] * cnt_min[block] + _max[block] * cnt_max[block] + offset[block] * sz[block];
  26.     return _min[block] * cnt_min[block] + offset[block] * sz[block];
  27. }
  28.  
  29. int main(void) {
  30.     ios_base::sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
  31.     //freopen("input.txt", "r", stdin);
  32.     //freopen("output.txt", "w", stdout);
  33.     int ntest;
  34.     cin >> ntest;
  35.     while (ntest--) {
  36.         cin >> n >> q;
  37.         for (int i = 1; i <= n; ++i) cin >> a[i];
  38.         for (int i = 1; i <= q; ++i) {
  39.             cin >> type[i] >> l[i] >> r[i];
  40.             if (type[i] == 3) cin >> x[i];
  41.         }
  42.         for (int st = 1; st <= q; st += step) {
  43.             memset(id, 0, sizeof id);
  44.             memset(sum, 0, sizeof sum);
  45.             memset(offset, 0, sizeof offset);
  46.  
  47.             int en = min(q, st + step - 1);
  48.             for (int i = st; i <= en; ++i) {
  49.                 id[l[i]] = id[r[i] + 1] = 1;
  50.             }
  51.             id[n + 1] = 1;
  52.             vector <pair <int, int> > block_order;
  53.             for (int i = 1; i <= n + 1; ++i) {
  54.                 id[i] += id[i-1];
  55.                 sum[id[i]] += a[i];
  56.                 if (id[i] != id[i-1]) {
  57.                     sort(block_order.begin(), block_order.end());
  58.                     for (int j = 0; j < block_order.size(); ++j)
  59.                         order[block_order[j].second] = j + 1;
  60.                     block_order.clear();
  61.  
  62.                     block_start[id[i]] = i;
  63.                     _min[id[i]] = _max[id[i]] = a[i], cnt_min[id[i]] = cnt_max[id[i]] = 1;
  64.                 }
  65.                 else change(a[i], id[i]);
  66.  
  67.                 if (i <= n) block_order.push_back(make_pair(a[i], i));
  68.             }
  69.             for (int i = 1; i <= id[n]; ++i) sz[i] = block_start[i+1] - block_start[i];
  70.  
  71.             for (int i = st; i <= en; ++i) {
  72.                 int lid = id[l[i]], rid = id[r[i]];
  73.                 if (type[i] == 1) {
  74.                     for (int j = lid; j <= rid; ++j) {
  75.                         if (_max[j] - _min[j] > 1) {
  76.                             _max[j] = -inf, _min[j] = inf, sum[j] = 0;
  77.                             for (int k = block_start[j]; k < block_start[j+1]; ++k) {
  78.                                 a[k] = sqrt(a[k] + offset[j]);
  79.                                 change(a[k], j);
  80.                                 sum[j] += a[k];
  81.                             }
  82.                         }
  83.                         else {
  84.                             _min[j] = sqrt(_min[j] + offset[j]);
  85.                             _max[j] = sqrt(_max[j] + offset[j]);
  86.                             if (_max[j] == _min[j]) cnt_min[j] = cnt_max[j] = sz[j];
  87.                         }
  88.                         offset[j] = 0;
  89.                     }
  90.                 }
  91.                 else if (type[i] == 2) {
  92.                     long long ans = 0;
  93.                     for (int j = lid; j <= rid; ++j) ans += get_sum(j);
  94.                     cout << ans << '\n';
  95.                 }
  96.                 else {
  97.                     for (int j = lid; j <= rid; ++j) offset[j] += x[i];
  98.                 }
  99.             }
  100.  
  101.             for (int i = 1; i <= n; ++i) {
  102.                 int j = id[i];
  103.                 if (_max[j] - _min[j] > 1) a[i] += offset[j];
  104.                 else if (_max[j] - _min[j] == 1) {
  105.                     if (order[i] <= cnt_min[j]) a[i] = _min[j] + offset[j];
  106.                     else a[i] = _max[j] + offset[j];
  107.                 }
  108.                 else a[i] = _min[j] + offset[j];
  109.             }
  110.         }
  111.     }
  112.     return 0;
  113. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement