中位数的话,可以考虑一下二分答案,然后把原序列转成01序列,看0和1的数量谁多就知道答案是大于mid还是小于mid了
这样如果不强制在线可以整体二分
但是强制在线了-_-
好吧,我们考虑维护mid逐渐增长,那么每次会有一些点从0变成1,我们需要的是每次在某一个mid下查询区间的最大连续和之类的东西,那么我们用主席树维护每个mid的时候的01序列即可
#include<iostream>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<cstdlib>
#include<cstdio>
#include<map>
#include<bitset>
#include<set>
#include<stack>
#include<vector>
#include<queue>
using namespace std;
#define MAXN 20010
#define MAXM 1000010
#define ll long long
#define eps 1e-8
#define MOD 1000000007
#define INF 1000000000
struct data{
int mnl;
int mnr;
int s;
friend data operator +(data x,data y){
data z;
z.s=x.s+y.s;
z.mnl=min(x.mnl,x.s+y.mnl);
z.mnr=min(y.mnr,y.s+x.mnr);
return z;
}
};
int n,m;
int a[MAXN];
map<int,int>h;
int g[MAXN];
int tls[MAXN],tln,mx;
int p[MAXN];
int rt[MAXN];
int son[MAXM][2];
data v[MAXM];
int tot;
int la;
bool cmp(int x,int y){
return a[x]<a[y];
}
inline void ud(int x){
v[x]=v[son[x][0]]+v[son[x][1]];
}
void change(int &x,int xx,int y,int z,int p){
x=++tot;
memcpy(son[x],son[xx],sizeof(son[x]));
if(y==z){
v[x].s=v[x].mnl=v[x].mnr=-1;
return ;
}
int mid=y+z>>1;
if(p<=mid){
change(son[x][0],son[xx][0],y,mid,p);
}else{
change(son[x][1],son[xx][1],mid+1,z,p);
}
ud(x);
}
void build(int &x,int y,int z){
x=++tot;
if(y==z){
v[x].s=1;
v[x].mnl=v[x].mnr=0;
return ;
}
int mid=y+z>>1;
build(son[x][0],y,mid);
build(son[x][1],mid+1,z);
ud(x);
}
data ask(int x,int y,int z,int l,int r){
if(y==l&&z==r){
return v[x];
}
int mid=y+z>>1;
if(r<=mid){
return ask(son[x][0],y,mid,l,r);
}else if(l>mid){
return ask(son[x][1],mid+1,z,l,r);
}else{
return ask(son[x][0],y,mid,l,mid)+ask(son[x][1],mid+1,z,mid+1,r);
}
}
bool OK(int mid,int x,int y,int xx,int yy){
int sm,sl,sr;
sm=ask(rt[mid],1,n,y,xx).s;
if(x==y){
sl=0;
}else{
sl=ask(rt[mid],1,n,x,y-1).mnr;
}
if(xx==yy){
sr=0;
}else{
sr=ask(rt[mid],1,n,xx+1,yy).mnl;
}
return sl+sr+sm<=0;
}
int main(){
int i,x,y,xx,yy;
int o[10];
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
tls[++tln]=a[i];
}
sort(tls+1,tls+tln+1);
for(i=1;i<=tln;i++){
if(tls[i]!=tls[i-1]||i==1){
g[h[tls[i]]=++mx]=tls[i];
}
}
for(i=1;i<=n;i++){
a[i]=h[a[i]];
p[i]=i;
}
sort(p+1,p+n+1,cmp);
int wzh=n;
build(rt[mx+1],1,n);
for(i=mx;i;i--){
rt[i]=rt[i+1];
while(a[p[wzh]]==i&&wzh){
change(rt[i],rt[i],1,n,p[wzh]);
wzh--;
}
}
scanf("%d",&m);
while(m--){
for(i=1;i<=4;i++){
scanf("%d",&o[i]);
((o[i]+=la)%=n)+=1;
}
sort(o+1,o+5);
x=o[1];
y=o[2];
xx=o[3];
yy=o[4];
int l=1,r=mx;
int ans;
while(l<=r){
int mid=l+r>>1;
if(OK(mid,x,y,xx,yy)){
ans=mid;
l=mid+1;
}else{
r=mid-1;
}
}
printf("%d\n",la=g[ans]);
}
return 0;
}
/*
5
170337785
271451044
22430280
969056313
206452321
3
3 1 0 2
2 3 1 4
3 1 4 0
*/