BZOJ
SOL
无法确定中位数 ? 我们可以考虑转化思路。
二分一个中位数,再判断是否合理。
根据本题中中位数的定义,只需要小于 它的 数的个数
≤
∣
l
e
n
2
∣
\le |{len \over2}|
≤∣2len∣。
我们可以将大于
i
i
i的数赋值成
1
1
1,小于的赋值成
−
1
-1
−1。
若
m
a
x
L
s
u
m
[
a
,
b
−
1
]
+
s
u
m
[
b
,
c
]
+
m
a
x
R
s
u
m
[
c
+
1
,
d
]
≥
0
若maxLsum[a,b-1]+sum[b,c]+maxRsum[c+1,d]\ge0
若maxLsum[a,b−1]+sum[b,c]+maxRsum[c+1,d]≥0,
i
i
i可能可以更大。
如何实现赋值操作 ? 用主席树增量法更改。
从小到大排序,对于“下一个数的主席树”,把当前数从
1
1
1改为
−
1
-1
−1即可。
代码好懂。
CODE
#include<bits/stdc++.h>
#define pf printf
#define sf scanf
#define cs const
#define ll long long
#define db double
#define ri register int
using namespace std;
#define in red()
inline int red()
{
int data=0;int w=1; char ch=0;
ch=getchar();
while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0' && ch<='9') data=(data<<3)+(data<<1)+ch-'0',ch=getchar();
return data*w;
}
cs int N=1e6+10,M=2e4+10;
#define lc(x) ch[x][0]
#define rc(x) ch[x][1]
int ch[N][2],rt[M],n,m,tot=0;
struct node{
int sum,lm,rm;
}val[N];
inline node merge(node a,node b){
node t;
t.sum=a.sum+b.sum;
t.lm=max(a.lm,a.sum+b.lm);
t.rm=max(b.rm,b.sum+a.rm);
return t;
}
inline int cpy(int x){++tot;ch[tot][0]=ch[x][0];ch[tot][1]=ch[x][1];return tot;}
inline void build(int l,int r,int &t){
t=++tot;
if(l==r)return val[t].lm=val[t].rm=val[t].sum=1,void();
int mid=(l+r)>>1;
build(l,mid,lc(t));build(mid+1,r,rc(t));
val[t]=merge(val[lc(t)],val[rc(t)]);
}
inline void insert(int p,int l,int r,int k,int &t){
t=cpy(p);
if(l==r)return val[t].lm=val[t].rm=val[t].sum=-1,void();
int mid=(l+r)>>1;
if(k<=mid)insert(lc(p),l,mid,k,lc(t));
else insert(rc(p),mid+1,r,k,rc(t));
val[t]=merge(val[lc(t)],val[rc(t)]);
}
inline node query(int p,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return val[p];
int mid=(l+r)>>1;
if(qr<=mid)return query(lc(p),l,mid,ql,qr);
else if(ql>mid)return query(rc(p),mid+1,r,ql,qr);
else return merge(query(lc(p),l,mid,ql,qr),query(rc(p),mid+1,r,ql,qr));
}
typedef pair<int,int> pi;
#define fi first
#define se second
pi a[M];
int q[4];
inline bool check(int k){
return query(rt[k],1,n,q[1],q[2]).sum+max(0,query(rt[k],1,n,q[0],q[1]-1).rm)+max(0,query(rt[k],1,n,q[2]+1,q[3]).lm)>=0;
}
inline int run(){
int l=1,r=n,mid;
while(l+1<r){
mid=(l+r)>>1;
if(check(mid))l=mid;
else r=mid;
}
return check(r) ? r : l;
}
signed main (){
n=in;
for(ri i=1;i<=n;++i){
a[i].fi=in;a[i].se=i;
}
sort(a+1,a+n+1);
build(1,n,rt[1]);
for(ri i=1;i<=n;++i)insert(rt[i],1,n,a[i].se,rt[i+1]);
m=in;
int ans=0;
while(m--){
for(ri i=0;i<4;++i)q[i]=in,q[i]=(q[i]+ans)%n+1;
sort(q,q+4);
cout<<(ans=a[run()].fi)<<'\n';
}
return 0;
}