Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #ifdef local
- #define debug(args...) qqbx(#args, args)
- template <typename ...T> void qqbx(const char *s, T ...a) {
- int cnt = sizeof...(T);
- ((std::cerr<<"\e[1;32m("<<s<<") = ("),...,(std::cerr<<a<<(--cnt?", ":")\e[0m\n")));
- }
- #else
- #define debug(...) ((void)0)
- #endif // local
- using namespace std;
- using lld = int64_t;
- const int N = 500000 + 5;
- struct node {
- int sz;
- lld tot;
- int sl, sr;
- node operator+(const node &rhs) const {
- if (sz == -1) return rhs;
- if (rhs.sz == -1) return *this;
- node r;
- r.tot = tot + rhs.tot + sr * rhs.sl;
- r.sl = sl + (sz == sl ? rhs.sl : 0);
- r.sr = rhs.sr + (rhs.sz == rhs.sr ? sr : 0);
- r.sz = sz + rhs.sz;
- return r;
- }
- };
- node nd[1 << 19];
- node vs[10 * (1<<20)];
- int tot;
- int offset_s[1<<20];
- int offset_p[1<<20];
- int mid[1<<20];
- bool le[N];
- int a[N];
- node query(int l, int r) {
- ++r;
- if (l == r) return {-1, 0, 0, 0};
- debug(l, r);
- // l += 1 << 19;
- // r += 1 << 19;
- int h = __lg(l ^ r) + 1;
- int id = (l + (1<<19)) >> h;
- /*
- debug(mid[id] - l, r - mid[id]);
- debug(suf[id].size());
- debug(pre[id].size());
- */
- return vs[offset_s[id] + mid[id] - l] + vs[offset_p[id] + r - mid[id]];
- }
- lld calc(int L, int i, int R, int n) {
- if (L == R) return 1;
- lld c = max(query(L, i).tot + i - L + 1, query(i, R).tot + R - i + 1);
- // cout << L << ", " << i << ", " << R << ": " << c << '\n';
- return c;
- }
- void build(int l, int r, int id) {
- if (r - l == 1)
- return;
- int m = (l + r) >> 1;
- build(l, m, id<<1);
- build(m, r, id<<1|1);
- int sz = m - l;
- offset_s[id] = tot, tot += sz + 1;
- offset_p[id] = tot, tot += sz + 1;
- mid[id] = m;
- node* pre = vs + offset_p[id];
- node* suf = vs + offset_s[id];
- for (int i = 0; i < sz; i++) {
- pre[i+1] = pre[i] + nd[m + i];
- suf[i+1] = suf[i] + nd[m - 1 - i];
- }
- }
- int main() {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- int n, q; cin >> n >> q;
- for (int i = 0; i < n; ++i) {
- cin >> a[i];
- }
- for (int i = 0; i < n - 1; ++i) {
- le[i] = a[i] <= a[i + 1];
- }
- for (int i = 0; i < (1<<19); i++)
- nd[i] = {-1, 0, 0, 0};
- for (int i = 0; i < n-1; i++)
- nd[i] = {1, le[i], le[i], le[i]};
- build(0, 1<<19, 1);
- while (q--) {
- int L, R; cin >> L >> R;
- --L, --R;
- int l = L - 1, r = R;
- while (r - l > 1) {
- int m = (l + r) >> 1;
- if (calc(L, m, R, n) < calc(L, m + 1, R, n)) r = m;
- else l = m;
- }
- cout << calc(L, l + 1, R, n) << '\n';
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment