[National Team] middle - Luogu P2839

Luogu P2839 - Portal

Middle

Subject description:

A sequence of length n, a, which is then provided to sequence through the rows b, where is defined as the number of bits b [n / 2], where a, b numeral from 0, remove the whole division.

You give a sequence length n s.
Such a query answer Q: s between a left end point [a, b], the sequence between the right end of the [c, d], the largest median.

Where a <b <c <d.
Reference numeral from 0 beginning position.
Use some of the ways to force you online.

Input formats:

The first line sequence length n.
Next, in the order given row n is a number.

Q. The next line
And Q lines each a, b, c, d, we make an inquiry on the answer is x (if this is the first interrogation of the x = 0).

Order array q = {(a + x)% n, (b + x)% n, (c + x)% n, (d + x)% n}.

After q from small to large, to make the real interrogation of a = q [0], b = q [1], c = q [2], d = q [3].

Output formats:

Q line of inquiry in order to give an answer.

Solution :

  1. First, for the median for a fixed interval, a half of the interval x where x is equal to the number greater than 1 is assigned, is assigned a number less than x -1, and if the interval is greater than or equal to 0, the x <= maximum median
  2. For the given topic section, the left and right end is not fixed, the value for b + 1 to c-1 is between must be considered, but a to b can record a maximum of suffix c to d to a maximum recording Similarly prefix, and then determines whether these three values ​​and> = 0 to

So you can use binary tree Chairman + However, I will not, Or do block, and for only the interval, prefixes, suffixes corresponding to the maximum value of the recording blocks in each memory block needs, and for the value does not exist, with a large force than its value can be updated, because the value It does not exist in the block, and its interval, prefixes and suffixes are equal and greater than a value of its presence.

Code :

#include<bits/stdc++.h>
using namespace std;
const int N = 2e4 + 7, B = 155, inf = 1e5;
int n, m, len, nn;
int l1, l2, r1, r2;
int a[N], h[N], blo[N];
int Lx[B][N], Rx[B][N], Sx[B][N];
template<class T> inline void read(T &x) {
    bool f = false; x = 0;
    char ch = getchar();
    while (ch<'0' || ch>'9') {if (ch == '-') f = true; ch = getchar();}
    while (ch>='0' && ch<='9') x = x * 10 + ch - '0', ch = getchar();
    if (f) x = -x;
}
inline void Init() {
    for (int i = 0; i <= B - 5; i++) {
        for (int j = 0; j <= len + 5; j++) {
            Lx[i][j] = Rx[i][j] = Sx[i][j] = -inf;
        }
    }
    for (int blk = 1; blk <= (n - 1) / nn + 1; blk ++) {
        int L = (blk - 1) * nn + 1, R = min(blk * nn, n);
        for (int i = L; i <= R; i++) {
            int nw = a[i], sum = 0;
            for (int j = L; j <= R; j++) {
                sum += a[j] >= nw ? 1 : -1;
            }
            Sx[blk][nw] = sum;
            sum = 0;
            for (int j = L; j <= R; j++) {
                sum += a[j] >= nw ? 1 : -1;
                Lx[blk][nw] = max(Lx[blk][nw], sum);
            }
            sum = 0;
            for (int j = R; j >= L; j--) {
                sum += a[j] >= nw ? 1 : -1;
                Rx[blk][nw] = max(Rx[blk][nw], sum);
            }
        }
        // Sx[blk][len + 1] = Lx[blk][len + 1] = Rx[blk][len + 1] = -inf;
        for (int i = len; i >= 1; i--) {
            Sx[blk][i] = max(Sx[blk][i], Sx[blk][i + 1]);
            Lx[blk][i] = max(Lx[blk][i], Lx[blk][i + 1]);
            Rx[blk][i] = max(Rx[blk][i], Rx[blk][i + 1]);
        }
    }
}
inline int getSum(int u, int v, int w) {
    if (u > v) return 0;
    int res = 0;
    if (blo[u] == blo[v]) {
        for (int i = u; i <= v; i++)
            res += a[i] >= w ? 1 : -1;
        return res;
    }
    for (int i = u; i <= nn * blo[u]; i++) 
        res += a[i] >= w ? 1 : -1;
    for (int i = blo[u] + 1; i <= blo[v] - 1; i++) 
        res += Sx[i][w];
    for (int i = nn * (blo[v] - 1) + 1; i <= v; i++) 
        res += a[i] >= w ? 1 : -1;
    return res;
}
inline int getLx(int u, int v, int w) {
    int mx = -inf, sum = 0;
    if (blo[u] == blo[v]) {
        for (int i = u; i <= v; i++) {
            sum += a[i] >= w ? 1 : -1;
            mx = max(mx, sum);
        }
        return mx;
    }
    for (int i = u; i <= nn * blo[u]; i++) {
        sum += a[i] >= w ? 1 : -1;
        mx = max(mx, sum);
    }
    for (int i = blo[u] + 1; i <= blo[v] - 1; i++) {
        mx = max(mx, sum + Lx[i][w]);
        sum += Sx[i][w];
    }
    for (int i = nn * (blo[v] - 1) + 1; i <= v; i++) {
        sum += a[i] >= w ? 1 : -1;
        mx = max(mx, sum);
    }
    return mx;
}
inline int getRx(int u, int v, int w) {
    int mx = -inf, sum = 0;
    if (blo[u] == blo[v]) {
        for (int i = v; i >= u; i--) {
            sum += a[i] >= w ? 1 : -1;
            mx = max(mx, sum);
        }
        return mx;
    }
    for (int i = v; i >= nn * (blo[v] - 1) + 1; i--) {
        sum += a[i] >= w ? 1 : -1;
        mx = max(mx, sum);
    }
    for (int i = blo[v] - 1; i >= blo[u] + 1; i--) {
        mx = max(mx, sum + Rx[i][w]);
        sum += Sx[i][w];
    }
    for (int i = nn * blo[u]; i >= u; i--) {
        sum += a[i] >= w ? 1 : -1;
        mx = max(mx, sum);
    }
    return mx;
}
inline bool judge(int k) {
    return getRx(l1, r1, k) + getSum(r1 + 1, l2 - 1, k) + getLx(l2, r2, k) >= 0;
}
int main() {
    read(n);
    nn = sqrt(n);
    for (int i = 1; i <= n; i++) {
        read(a[i]);
        h[i] = a[i];
        blo[i] = (i - 1) / nn + 1;
    }
    sort(h + 1, h + 1 + n);
    len = unique(h + 1, h + 1 + n) - h - 1;
    for (int i = 1; i <= n; i++) {
        a[i] = lower_bound(h + 1, h + 1 + len, a[i]) - h;
    }
    Init(); read(m);
    int prv = 0, q[5];
    for (int i = 1; i <= m; i++) {
        read(l1), read(r1), read(l2), read(r2);
        q[1] = (l1 + prv) % n; q[2] = (r1 + prv) % n;
        q[3] = (l2 + prv) % n; q[4] = (r2 + prv) % n;
        sort(q + 1, q + 1 + 4);
        l1 = q[1] + 1, r1 = q[2] + 1, l2 = q[3] + 1, r2 = q[4] + 1;
        int l = 1, r = len, pos;
        while (l <= r) {
            int mid = (l + r) >> 1;
            if (judge(mid)) pos = mid, l = mid + 1;
            else r = mid - 1;
        }
        printf("%d\n", prv = h[pos]);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/bryane/p/11708942.html