Advertisement
Kevin_Zhang

Untitled

Jan 28th, 2021
1,211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.50 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define pb emplace_back
  3. #define AI(i) begin(i), end(i)
  4. template<class T> bool chmax(T &a, T b) { return a < b && (a = b, true); }
  5. template<class T> bool chmin(T &a, T b) { return b < a && (a = b, true); }
  6. using namespace std;
  7. using ll = long long;
  8. #ifdef KEV
  9. #define DE(args...) kout("[ " + string(#args) + " ] = ", args)
  10. void debug(auto L, auto R) { while (L < R) cerr << *L << " \n"[next(L)==R], ++L; }
  11. void kout(){ cerr << endl; }
  12. template<class T1, class ...T2> void kout(T1 a, T2 ...e) { cerr << a << ' ', kout(e...); }
  13. #else
  14. #define DE(...) 0
  15. #define debug(...) 0
  16. #endif
  17. // What I should check
  18. // 1. overflow
  19. // 2. corner cases
  20. // Enjoy the problem instead of hurrying to AC
  21. // Good luck !
  22. #define int ll
  23. // now inf is big enough
  24. const int MAX_N = 300010;
  25. const ll inf = 1ll << 55;
  26. // !Warning, you should update after push in 吉如一
  27.  
  28. ll n, a[MAX_N], q;
  29.  
  30. struct node {
  31.     ll mx, sec, cntmx, len, sum, at, mt;
  32.     node(ll v = 0) {
  33.         mx = sum = v;
  34.         sec = -inf;
  35.         mt = inf;
  36.         len = cntmx = 1;
  37.         at = 0;
  38.     }
  39.     void operator += (ll v) {
  40.         mx += v, sec += v, sum += v * len, at += v, mt += v;
  41.     }
  42.     // return true if need push
  43.     bool chmn(ll v) {
  44.         if (v >= mx) return false;
  45.         assert(v <= mt);
  46.         sum -= (mx - v) * cntmx;
  47.         mt = mx = v;
  48.         return sec <= v && cntmx < len;
  49.     }
  50.     void updatemx(node a) {
  51.         if (chmax(mx, a.mx)) {
  52.             cntmx = a.cntmx;
  53.             chmax(sec, a.sec);
  54.         }
  55.         else if (mx == a.mx)
  56.             cntmx += a.cntmx;
  57.         else chmax(sec, a.mx);
  58.     }
  59.     node (node a, node b) :
  60.         mx(-inf), sec(-inf), cntmx(0), len(a.len + b.len), sum(a.sum + b.sum), at(0), mt(inf) {
  61.             updatemx(a), updatemx(b);
  62.         }
  63. };
  64.  
  65. void brutemn(int l, int r, int x) {
  66.     for (int i = l;i < r;++i)
  67.         chmin(a[i], x);
  68. }
  69. void brutead(int l, int r, int x) {
  70.     for (int i = l;i < r;++i)
  71.         a[i] += x;
  72. }
  73. ll brutesum(int l, int r) {
  74.     ll res = 0;
  75.     for (int i = l;i < r;++i)
  76.         res += a[i];
  77.     return res;
  78. }
  79. ll brutemx(int l, int r) {
  80.     ll res = 0;
  81.     for (int i = l;i < r;++i)
  82.         chmax(res, a[i]);
  83.     return res;
  84. }
  85.  
  86. struct sgt {
  87.     vector<node> val;
  88.     int n;
  89.     void update(int i) {
  90.         if (i >= n || i == 0) return;
  91.         ll &at = val[i].at, &mt = val[i].mt;
  92.         if (at) {
  93.             val[i<<1] += at;
  94.             val[i<<1|1] += at;
  95.             at = 0;
  96.         }
  97.         if (mt < inf) {
  98.             if (val[i<<1].chmn(mt))
  99.                 update(i<<1);
  100.             if (val[i<<1|1].chmn(mt))
  101.                 update(i<<1|1);
  102.         }
  103.  
  104.         val[i] = node(val[i<<1], val[i<<1|1]);
  105.  
  106.         assert(at == 0 && mt == inf);
  107.     }
  108.     // Yes I have cleared add tag and chmin tag
  109.     sgt(int _n) : n(_n) {
  110.         val.resize(n<<1);
  111.         for (int i = 0;i < n;++i)
  112.             val[i + n] = node(a[i]);
  113.         for (int i = n-1;i > 0;--i)
  114.             update(i);
  115.     }
  116.     void pa(int p) {
  117.         for (int i = 18;i > 0;--i)
  118.             update(p >> i);
  119.     }
  120.     void smn(int i, int x) {
  121.         if (val[i].chmn(x))
  122.             update(i);
  123.     }
  124.     void chmnlr(int l, int r, int x) {
  125.         l += n, r += n;
  126.         pa(l), pa(r-1);
  127.         int sl = l, sr = r-1;
  128.         for (;l < r;l>>=1, r>>=1) {
  129.             if (l&1) smn(l++, x);
  130.             if (r&1) smn(--r, x);
  131.         }
  132.         for (;sl >>= 1, sr >>= 1;) {
  133.             update(sl), update(sr);
  134.         }
  135.     }
  136.     void addlr(int l, int r, int x) {
  137.         l += n, r += n;
  138.         pa(l), pa(r-1);
  139.         int sl = l, sr = r-1;
  140.         for (;l < r;l>>=1, r>>=1) {
  141.             if (l&1) val[l++] += x;
  142.             if (r&1) val[--r] += x;
  143.         }
  144.         for (;sl >>= 1, sr >>= 1;) {
  145.             update(sl), update(sr);
  146.         }
  147.  
  148.     }
  149.     node qry(int l, int r) {
  150.  
  151.         l += n, r += n;
  152.         pa(l), pa(r-1);
  153.         node res(0);
  154.         for (;l < r;l>>=1, r>>=1) {
  155.             if (l&1) res = node(res, val[l++]);
  156.             if (r&1) res = node(res, val[--r]);
  157.         }
  158.         return res;
  159.     }
  160. };
  161.  
  162. int32_t main() {
  163.     ios_base::sync_with_stdio(0), cin.tie(0);
  164.     cin >> n >> q;
  165.     for (int i = 0;i < n;++i)
  166.         cin >> a[i];
  167.    
  168.     sgt tree(n);
  169.     ll out = -1;
  170.     while (q--) {
  171.         int t, l, r, x;
  172.         cin >> t >> l >> r; --l;
  173.  
  174.         if (t <= 2) {
  175.             cin >> x;
  176.             if (t == 1) tree.chmnlr(l, r, x);
  177.             if (t == 2) tree.addlr(l, r, x);
  178.         }
  179.         else {
  180.             auto res = tree.qry(l, r);
  181.             if (t == 3) cout << res.sum << '\n', out = res.sum;
  182.             if (t == 4) cout << res.mx << '\n', out = res.mx;
  183.         }
  184.  
  185. #ifdef KEV
  186.         DE(t, l, r, x);
  187.         if (t == 1) brutemn(l, r, x);
  188.         if (t == 2) brutead(l, r, x);
  189.         if (t == 3) {
  190.             DE(brutesum(l, r), out);
  191.             assert(brutesum(l, r) == out);
  192.         }
  193.         if (t == 4) {
  194.             DE(brutemx(l, r), out);
  195.             assert(brutemx(l, r) == out);
  196.         }
  197. //      const int len = 3;
  198. //      for (int i = 0;i < n;++i) {
  199. //          assert(tree.qry(i, i+1).sum == brutesum(i, i+1));
  200. //      }
  201. #endif
  202. //
  203. ////        DE(t, l, r, x);
  204. //      for (int i = 0;i < n;++i)
  205. //          cerr << tree.qry(i, i+1).sum << " \n"[i==n];
  206. //
  207. //      cerr << endl;
  208. //      cout << endl;
  209.     }
  210. }
  211.  
  212.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement