bingxuan9112

Untitled

Jul 10th, 2021
695
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.59 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #ifdef local
  3. #define debug(args...) qqbx(#args, args)
  4. template <typename ...T> void qqbx(const char *s, T ...a) {
  5.     int cnt = sizeof...(T);
  6.     ((std::cerr<<"\e[1;32m("<<s<<") = ("),...,(std::cerr<<a<<(--cnt?", ":")\e[0m\n")));
  7. }
  8. #else
  9. #define debug(...) ((void)0)
  10. #endif // local
  11. using namespace std;
  12. using lld = int64_t;
  13. const int N = 500000 + 5;
  14.  
  15. struct node {
  16.     int sz;
  17.     lld tot;
  18.         int sl, sr;
  19.     node operator+(const node &rhs) const {
  20.         if (sz == -1) return rhs;
  21.         if (rhs.sz == -1) return *this;
  22.         node r;
  23.         r.tot = tot + rhs.tot + sr * rhs.sl;
  24.         r.sl = sl + (sz == sl ? rhs.sl : 0);
  25.         r.sr = rhs.sr + (rhs.sz == rhs.sr ? sr : 0);
  26.         r.sz = sz + rhs.sz;
  27.         return r;
  28.     }
  29. };
  30.  
  31. node nd[1 << 19];
  32. node vs[10 * (1<<20)];
  33. int tot;
  34. int offset_s[1<<20];
  35. int offset_p[1<<20];
  36. int mid[1<<20];
  37.  
  38. bool le[N];
  39. int a[N];
  40.  
  41. node query(int l, int r) {
  42.     ++r;
  43.     if (l == r) return {-1, 0, 0, 0};
  44.     debug(l, r);
  45.     // l += 1 << 19;
  46.     // r += 1 << 19;
  47.     int h = __lg(l ^ r) + 1;
  48.     int id = (l + (1<<19)) >> h;
  49.     /*
  50.     debug(mid[id] - l, r - mid[id]);
  51.     debug(suf[id].size());
  52.     debug(pre[id].size());
  53.     */
  54.     return vs[offset_s[id] + mid[id] - l] + vs[offset_p[id] + r - mid[id]];
  55. }
  56.  
  57. lld calc(int L, int i, int R, int n) {
  58.     if (L == R) return 1;
  59.     lld c = max(query(L, i).tot + i - L + 1, query(i, R).tot + R - i + 1);
  60.     // cout << L << ", " << i << ", " << R << ": " << c << '\n';
  61.     return c;
  62. }
  63.  
  64. void build(int l, int r, int id) {
  65.     if (r - l == 1)
  66.         return;
  67.     int m = (l + r) >> 1;
  68.     build(l, m, id<<1);
  69.     build(m, r, id<<1|1);
  70.     int sz = m - l;
  71.     offset_s[id] = tot, tot += sz + 1;
  72.     offset_p[id] = tot, tot += sz + 1;
  73.     mid[id] = m;
  74.     node* pre = vs + offset_p[id];
  75.     node* suf = vs + offset_s[id];
  76.     for (int i = 0; i < sz; i++) {
  77.         pre[i+1] = pre[i] + nd[m + i];
  78.         suf[i+1] = suf[i] + nd[m - 1 - i];
  79.     }
  80. }
  81.  
  82.  
  83. int main() {
  84.     ios_base::sync_with_stdio(false);
  85.     cin.tie(nullptr);
  86.     int n, q; cin >> n >> q;
  87.     for (int i = 0; i < n; ++i) {
  88.         cin >> a[i];
  89.     }
  90.     for (int i = 0; i < n - 1; ++i) {
  91.         le[i] = a[i] <= a[i + 1];
  92.     }
  93.  
  94.         for (int i = 0; i < (1<<19); i++)
  95.             nd[i] = {-1, 0, 0, 0};
  96.         for (int i = 0; i < n-1; i++)
  97.             nd[i] = {1, le[i], le[i], le[i]};
  98.         build(0, 1<<19, 1);
  99.     while (q--) {
  100.         int L, R; cin >> L >> R;
  101.         --L, --R;
  102.         int l = L - 1, r = R;
  103.         while (r - l > 1) {
  104.             int m = (l + r) >> 1;
  105.             if (calc(L, m, R, n) < calc(L, m + 1, R, n)) r = m;
  106.             else l = m;
  107.         }
  108.         cout << calc(L, l + 1, R, n) << '\n';
  109.     }
  110.     return 0;
  111. }
  112.  
Advertisement
Add Comment
Please, Sign In to add comment