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
| #include <cstdio> #include <algorithm>
inline int read() { char ch; int x(0), f(1); while ((ch = getchar()) < 48) if (ch == '-') f = -1; do x = x * 10 + ch - 48; while ((ch = getchar()) >= 48); return x * f; } struct Max {inline int operator () (const int x, const int y) const {return x > y ? x : y;}} max; const int N = 20005, n = read(); int a[N], Key[N]; struct I_want_to_AKIOI { int v, idx, rnk; inline bool operator < (const I_want_to_AKIOI x) const {return v < x.v;} } b[N];
struct Chairman_tree { struct node { int v, v1, v2, ls, rs; } a[N << 5]; int rt[N], tot, x, y, ans, s;
inline void build() {make_tree(rt[1] = tot = 1, 1, n);} void make_tree(const int p, const int l, const int r) { a[p].v = a[p].v1 = a[p].v2 = r - l + 1; if (l != r) make_tree(a[p].ls = ++ tot, l, l + r >> 1), make_tree(a[p].rs = ++ tot, (l + r >> 1) + 1, r); }
inline void Update() { int k(1); for (int i(1); i <= n; ++ i)
x = b[i].idx, rt[++ k] = ++ tot, update(rt[k], 1, n, rt[k - 1]); } void update(const int p, const int l, const int r, const int root) { if (l == r) {a[p].v = -1, a[p].v1 = a[p].v2 = 0; return;} int mid(l + r >> 1), &ls(a[p].ls), &rs(a[p].rs); if (mid >= x) { update((ls ? ls : ls = ++ tot), l, mid, a[root].ls); if (!rs) rs = a[root].rs; } else { update((rs ? rs : rs = ++ tot), mid + 1, r, a[root].rs); if (!ls) ls = a[root].ls; } a[p].v = a[ls].v + a[rs].v, a[p].v1 = max(a[ls].v1, a[ls].v + a[rs].v1), a[p].v2 = max(a[rs].v2, a[rs].v + a[ls].v2); }
inline int Query(const int A, const int B, const int C, const int D) { int l(1), r(n), Ans(0); while (l <= r) { x = B, y = C; int mid(l + r >> 1), sum(query(rt[mid], 1, n)); x = A, y = B - 1, s = ans = 0, queryr(rt[mid], 1, n), sum += ans; x = C + 1, y = D, s = ans = 0, queryl(rt[mid], 1, n), sum += ans; sum >= 0 ? Ans = mid, l = mid + 1 : r = mid - 1; } return Ans; } void queryl(const int p, const int l, const int r) { if (x <= l && r <= y) {ans = max(ans, s + a[p].v1), s += a[p].v; return;} int mid(l + r >> 1); if (mid >= x) queryl(a[p].ls, l, mid); if (mid < y) queryl(a[p].rs, mid + 1, r); } void queryr(const int p, const int l, const int r) { if (x <= l && r <= y) {ans = max(ans, s + a[p].v2), s += a[p].v; return;} int mid(l + r >> 1); if (mid < y) queryr(a[p].rs, mid + 1, r); if (mid >= x) queryr(a[p].ls, l, mid); } int query(const int p, const int l, const int r) const { if (x <= l && r <= y) return a[p].v; int mid(l + r >> 1), sum(0); if (mid >= x) sum += query(a[p].ls, l, mid); if (mid < y) sum += query(a[p].rs, mid + 1, r); return sum; } } Tree;
int main() { int last(0), m; Tree.build(); for (int i(1); i <= n; ++ i) b[i].idx = i, b[i].v = a[i] = read(); std::sort(b + 1, b + n + 1); Key[b[1].rnk = 1] = b[1].v; for (int i(2); i <= n; ++ i) Key[b[i].rnk = (b[i].v == b[i - 1].v ? b[i - 1].rnk : b[i - 1].rnk + 1)] = b[i].v; std::sort(a + 1, a + n + 1); Tree.Update(), m = read(); while (m --) { int q[4] = {read(), read(), read(), read()}; for (int i(0); i < 4; ++ i) q[i] = (q[i] + last) % n + 1; std::sort(q, q + 4); printf("%d\n", last = a[Tree.Query(q[0], q[1], q[2], q[3])]); } }
|