首先 [b,c] 是必選的, 然後選一段 [a,b) 的後綴和一段 (c,d] 的前綴(都可空)。
對於中位數(這裏中位數採用這道題的定義)有個常見的處理方式: 二分 mid, 將 <mid 的設爲 -1, 其餘設爲 1, 求總和, 若總和 >0, 則說明 ≥mid 的佔到了一半以上, 即中位數 ≥mid。
採用這種處理方式, 二分中位數, 由於要中位數儘量大, 所以要貪心, 選後綴和前綴使得大於等於 mid 的減去小於等於 mid 的最大。
可以用可持久化線段樹, 具體地, 類似笛卡爾樹, 從小到大插入元素, 找出最大的前綴和後綴, 是可並信息, 可做。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e4 + 23, SZ = 17 * 2e4 + 233;
int n;
struct Seq { int i, a; } seq[N];
bool cmp(Seq s1, Seq s2) { return s1.a > s2.a; }
struct dat {
int siz, all, mxpre, mxsuf;
dat(int sz, int a, int p, int s) : siz(sz), all(a), mxpre(p), mxsuf(s) {
}
dat() {
}
} t[SZ];
dat mg(dat lef, dat rig) {
return dat( lef.siz + rig.siz, lef.all + rig.all, max(lef.mxpre, lef.all + rig.mxpre), max(rig.mxsuf, rig.all + lef.mxsuf) );
}
int tot, Root[N], ls[SZ], rs[SZ];
void ins(int p, int &q, int l, int r, int x) {
q = ++tot;
if(l == r)
{ t[q] = dat(1, 1, 1, 1); return;}
ls[q] = ls[p], rs[q] = rs[p];
int mid = (l+r) >> 1;
if(x<=mid)
ins(ls[p], ls[q], l, mid, x);
else
ins(rs[p], rs[q], mid+1, r, x);
t[q] = mg((ls[q]?t[ls[q]]:dat(mid-l+1,-(mid-l+1),0,0)), (rs[q]?t[rs[q]]:dat(r-mid,-(r-mid),0,0)));
}
dat ask(int me, int l, int r, int x, int y) {
if(x<=l && r<=y) return (me ? t[me] : dat(r-l+1, -(r-l+1), 0, 0));
int mid = (l+r) >> 1;
if(x<=mid && y>mid) return mg(ask(ls[me], l, mid, x, y), ask(rs[me], mid+1, r, x, y));
if(x<=mid) return ask(ls[me], l, mid, x, y);
if(y>mid) return ask(rs[me], mid+1, r, x, y);
}
bool chk(int mid, int a, int b, int c, int d) {
int base = ask(Root[mid], 1, n, b, c).all + ask(Root[mid], 1, n, a, b-1).mxsuf + ask(Root[mid], 1, n, c+1, d).mxpre;
return base >= 0;
}
int sol(int a, int b, int c, int d) {
int l=1, r=n;
while(l!=r) {
int mid = (l+r) >> 1;
chk(mid, a, b, c, d) ? r=mid : l=mid+1;
}
return seq[l].a;
}
int main()
{
scanf("%d", &n);
for(int i=1; i<=n; ++i) scanf("%d", &seq[i].a), seq[i].i = i;
sort(seq+1, seq+1+n, cmp);
for(int i=1; i<=n; ++i) ins(Root[i-1], Root[i], 1, n, seq[i].i);
int Q;
scanf("%d", &Q);
int q[4] = {0}, las = 0;
while(Q--)
{
for(int i=0; i<4; ++i) { scanf("%d", &q[i]); q[i] = (q[i] + las) % n + 1; }
sort(q, q+4);
las = sol(q[0], q[1], q[2], q[3]);
cout << las << '\n';
}
return 0;
}