1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| #include <bits/stdc++.h> #define FF std::function #define fi first #define se second #define STC static using PII = std::pair<int, int>; const int N = 1e5 + 100, INF = 0x3f3f3f3f; namespace FR { const int L = N << 1; struct Tree{ int lc, rc, dat; } tr[N]; struct Block{ int l, r, tp; } b[N]; int dfn[N], bid[L], cnt = 0, rt, num = 0, B, bk[L]; PII dat[L]; template<class T> bool cmn(T &x, T y){ return y < x ? x = y, true : false; } namespace ST { const int D = 18; int lg2[L]; PII mn[L][D]; void init() { lg2[1] = 0; for (int i = 2; i <= num; ++i) lg2[i] = lg2[i >> 1] + 1; for (int i = 1; i <= num; ++i) mn[i][0] = dat[b[i].l + bk[b[i].tp] - 1]; for (int j = 1, t = lg2[num]; j <= t; ++j) for (int i = 1; i <= num - (1 << j) + 1; ++i) mn[i][j] = std::min(mn[i][j - 1], mn[i + (1 << (j - 1))][j - 1]); } PII ask(int l, int r) { if (l > r) return {INF, INF}; int t = lg2[r - l + 1]; return std::min(mn[l][t], mn[r - (1 << t) + 1][t]); } } void init(int len, int x[]) { FF<void(int, int[])> bct = [&](int len, int x[]) { STC int stk[N]; int top = 0; for (int i = 1; i <= len; ++i) tr[i].dat = x[i]; for (int i = 1, k; i <= len; ++i) { for (k = top; k && tr[stk[k]].dat < tr[i].dat; --k); if (k) tr[stk[k]].rc = i; if (k < top) tr[i].lc = stk[k + 1]; stk[top = k + 1] = i; } rt = stk[1]; } ; bct(len, x); FF<void(int, int)> dfs = [&](int x, int dep) { dfn[x] = ++cnt, dat[cnt] = {dep, x}; if (tr[x].lc) dfs(tr[x].lc, dep + 1), dat[++cnt] = {dep, x}; if (tr[x].rc) dfs(tr[x].rc, dep + 1), dat[++cnt] = {dep, x}; } ; dfs(rt, 1); B = log2(cnt) / 2 + 1; for (int i = 1; i <= cnt; i += B) b[++num].l = i, b[num].r = i + B - 1; for (int i = cnt + 1; i <= b[num].r; ++i) dat[i] = {INF, INF}; for (int i = 1; i <= num; ++i) for (int j = b[i].l; j <= b[i].r; ++j) bid[j] = i; FF<void(int)> calc = [&](int x) { bk[x] = 1; for (int i = 2, mn = 0, sum = 0; i <= B; ++i) { if ((x >> (i - 1)) & 1) ++sum; else --sum; if (cmn(mn, sum)) bk[x] = i; } } ; FF<int(Block)> get_tp = [&](Block x) { int res = 0; for (int i = x.l + 1; i <= x.r; ++i) res |= (dat[i].fi - dat[i - 1].fi >= 0 ? 1 : 0) << (i - x.l); return res; } ; for (int i = (1 << B) - 1; ~i; --i) calc(i); for (int i = 1; i <= num; ++i) b[i].tp = get_tp(b[i]); ST::init(); } PII to_ask(int l, int r) { if (l > r) return to_ask(r, l); FF<PII(int, int)> bask = [&](int l, int r) { Block &x = b[bid[l]]; int t = x.tp, ll = l - x.l + 1, rr = r - x.l + 1; t >>= ll - 1; t |= ((1 << (rr - ll + 1)) - 1) ^ ((1 << B) - 1); return dat[l + bk[t] - 1]; } ; if (bid[l] == bid[r]) return bask(l, r); PII res = std::min(bask(l, b[bid[l]].r), bask(b[bid[r]].l, r)); if (bid[r] - bid[l] > 1) cmn(res, ST::ask(bid[l] + 1, bid[r] - 1)); return res; } int ask(int l, int r){ return tr[to_ask(dfn[l], dfn[r]).se].dat; } } int n, m, a[N]; int main() { scanf("%d %d", &n, &m); for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); FR::init(n, a); for (int l, r; m--; ) scanf("%d %d", &l, &r), printf("%d\n", FR::ask(l, r)); return 0; }
|