[LG2839] [National Team] middle

[LG2839] [National Team] middle

Face questions

Luo Valley

answer

According to the median routine request, we dichotomous answer \ (mid \) , greater than or equal to \ (mid \) number is set to \ (1 \) , otherwise \ (- 1 \) .

If a range equal to and greater than \ (0 \) , the answer may be larger, and vice versa.

For this problem, we can just maintain the \ ([b + 1, c -1] \) after two minutes between answers and, \ ([A, B] \) of the maximum right section and, \ ([C, D ] \) is the largest segment and left to determine whether the three add up to greater than zero.

We maintain these three and then, in accordance with the right value of the prefix, built Chairman of the tree on the line.

Code

#include <iostream> 
#include <cstdio> 
#include <cstdlib> 
#include <cstring> 
#include <cmath> 
#include <algorithm> 
using namespace std;
inline int gi() {
    register int data = 0, w = 1; 
    register char ch = 0; 
    while (!isdigit(ch) && ch != '-') ch = getchar(); 
    if (ch == '-') w = -1, ch = getchar(); 
    while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar(); 
    return w * data; 
} 
const int MAX_N = 2e4 + 5; 
struct Info { 
    int lmax, rmax, sum;
    Info () {lmax = rmax = -1, sum = 0; } 
    Info (int lmax, int rmax, int sum) : lmax(lmax), rmax(rmax), sum(sum) { } 
} ; 
Info operator + (Info l, Info r) { 
    Info res; 
    res.lmax = max(l.lmax, l.sum + r.lmax); 
    res.rmax = max(r.rmax, r.sum + l.rmax);
    res.sum = l.sum + r.sum; 
    return res; 
} 
struct Node { int ls, rs; Info v; } t[MAX_N * 20]; 
int rt[MAX_N], tot = 0; 
void build(int &o, int l, int r) { 
    o = ++tot; 
    t[o].v = (Info){r - l + 1, r - l + 1, r - l + 1}; 
    if (l == r) return ;
    int mid = (l + r) >> 1; 
    build(t[o].ls, l, mid);
    build(t[o].rs, mid + 1, r); 
} 
void insert(int &o, int p, int l, int r, int pos) { 
    o = ++tot, t[o] = t[p]; 
    if (l == r) return (void)(t[o].v = (Info){-1, -1, -1}); 
    int mid = (l + r) >> 1; 
    if (pos <= mid) insert(t[o].ls, t[p].ls, l, mid, pos); 
    else insert(t[o].rs, t[p].rs, mid + 1, r, pos); 
    t[o].v = t[t[o].ls].v + t[t[o].rs].v; 
} 
Info query(int o, int l, int r, int ql, int qr) { 
    if (ql <= l && r <= qr) return t[o].v; 
    int mid = (l + r) >> 1; Info res; 
    if (ql <= mid) res = res + query(t[o].ls, l, mid, ql, qr);
    if (qr > mid) res = res + query(t[o].rs, mid + 1, r, ql, qr); 
    return res; 
} 
int N, id[MAX_N], a[MAX_N], q[5]; 
bool check(int mid) { 
    int val = 0; 
    if (q[1] + 1 <= q[2] - 1) val += query(rt[mid], 1, N, q[1] + 1, q[2] - 1).sum; 
    val += query(rt[mid], 1, N, q[0], q[1]).rmax; 
    val += query(rt[mid], 1, N, q[2], q[3]).lmax; 
    return val >= 0; 
} 
bool cmp(const int &x, const int &y) { return a[x] < a[y]; } 
int main() { 
#ifndef ONLINE_JUDGE 
    freopen("cpp.in", "r", stdin); 
#endif 
    N = gi(); build(rt[1], 1, N); 
    for (int i = 1; i <= N; i++) a[i] = gi(), id[i] = i; 
    sort(&id[1], &id[N + 1], cmp); 
    for (int i = 2; i <= N; i++) insert(rt[i], rt[i - 1], 1, N, id[i - 1]); 
    for (int Q = gi(), ans = 0; Q--; ) { 
        for (int i = 0; i < 4; i++) q[i] = (gi() + ans) % N + 1;
        sort(&q[0], &q[4]);
        int l = 1, r = N;
        while (l <= r) {
            int mid = (l + r) >> 1; 
            if (check(mid)) ans = a[id[mid]], l = mid + 1;
            else r = mid - 1; 
        } 
        printf("%d\n", ans); 
    } 
    return 0;
}

Guess you like

Origin www.cnblogs.com/heyujun/p/11695299.html