#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using Int = long long; template ostream &operator<<(ostream &os, const pair &a) { return os << "(" << a.first << ", " << a.second << ")"; }; template void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; } template bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; } template bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; } template struct SegmentTree { const OpTT opTT; const OpST opST; const OpSS opSS; const T idT; const S idS; int n; vector ts; vector ss; SegmentTree(int n_, const OpTT opTT, const OpST opST, const OpSS opSS, const T &idT, const S &idS) : opTT(opTT), opST(opST), opSS(opSS), idT(idT), idS(idS) { for (n = 1; n < n_; n <<= 1) {} ts.assign(n << 1, idT); ss.assign(n << 1, idS); } T &at(int a) { return ts[n + a]; } void build() { for (int a = n; --a; ) ts[a] = opTT(ts[a << 1], ts[a << 1 | 1]); } T query(int a, int b, const S &s) { return query(1, 0, n, a, b, s); } private: T query(int u, int l, int r, int a, int b, const S &s) { if (a < l) a = l; if (b > r) b = r; if (a >= b) return idT; if (a == l && b == r) { ts[u] = opST(s, ts[u], r - l); ss[u] = opSS(s, ss[u]); return ts[u]; } const int uL = u << 1, uR = u << 1 | 1; const int mid = (l + r) >> 1; // speed-up: if (ss[u] != idS) if (ss[u] != idS) { ts[uL] = opST(ss[u], ts[uL], mid - l); ts[uR] = opST(ss[u], ts[uR], r - mid); ss[uL] = opSS(ss[u], ss[uL]); ss[uR] = opSS(ss[u], ss[uR]); ss[u] = idS; } const T resL = query(uL, l, mid, a, b, s); const T resR = query(uR, mid, r, a, b, s); ts[u] = opTT(ts[uL], ts[uR]); return opTT(resL, resR); } }; constexpr int MAX_N = 20010; constexpr int MAX_Q = 20010; #ifdef LOCAL constexpr int B = 3; #else constexpr int B = 141; #endif int N, Q; int A[MAX_N]; struct Query { int l, r, id; }; Query P[MAX_Q]; int ans[MAX_Q]; int l, r; int bitL[MAX_N], bitR[MAX_N]; int now; void bitAdd(int *bit, int pos, int val) { for (int x = pos; x < N; x |= x + 1) bit[x] += val; } int bitSum(int *bit, int pos) { int ret = 0; for (int x = pos - 1; x >= 0; x = (x & (x + 1)) - 1) ret += bit[x]; return ret; } int opTT(int t0, int t1) { return min(t0, t1); } int opST(int s, int t, int sz) { return s + t; } int opSS(int s0, int s1) { return s0 + s1; } using Seg = SegmentTree; Seg *seg; void addL() { now += (l - bitSum(bitL, A[l] + 1)); now += bitSum(bitR, A[l]); bitAdd(bitL, A[l], +1); seg->query(0, A[l], +1); ++l; } void remL() { --l; bitAdd(bitL, A[l], -1); now -= (l - bitSum(bitL, A[l] + 1)); now -= bitSum(bitR, A[l]); seg->query(0, A[l], -1); } void addR() { --r; now += (l - bitSum(bitL, A[r] + 1)); now += bitSum(bitR, A[r]); bitAdd(bitR, A[r], +1); seg->query(A[r] + 1, N, +1); } void remR() { now -= (l - bitSum(bitL, A[r] + 1)); now -= bitSum(bitR, A[r]); bitAdd(bitR, A[r], -1); seg->query(A[r] + 1, N, -1); ++r; } int main() { for (; ~scanf("%d%d", &N, &Q); ) { for (int i = 0; i < N; ++i) { scanf("%d", &A[i]); --A[i]; } for (int q = 0; q < Q; ++q) { scanf("%d%d", &P[q].l, &P[q].r); --P[q].l; P[q].id = q; } sort(P, P + Q, [](const Query &a, const Query &b) { const int ax = a.l / B; const int bx = b.l / B; return ((ax != bx) ? (ax < bx) : (ax & 1) ? (a.r > b.r) : (a.r < b.r)); }); l = 0; r = N; fill(bitL, bitL + N, 0); fill(bitR, bitR + N, 0); now = 0; seg = new Seg(N, &opTT, &opST, &opSS, N + 1, 0); for (int j = 0; j < N; ++j) { seg->at(j) = 0; } seg->build(); for (int q = 0; q < Q; ++q) { // cerr<<"query "< P[q].l; remL()) {} for (; r > P[q].r; addR()) {} for (; r < P[q].r; remR()) {} // cerr<<" now = "<query(j,j+1,0);}cerr<query(0, N, 0); } for (int q = 0; q < Q; ++q) { printf("%d\n", ans[q]); } } return 0; }