题目大意:给定一个长度为n的序列,求当子序列s的左端点在[a,b],右端点在[c,d]时的最大中位数
其中当序列长度为偶数时中位数定义为中间两个数中较大的那个
区间处理那里 [b,c]是必选的 [a,b)和(c,d]每段取最大加和 否则re恒>=0
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 20200
using namespace std;
struct abcd{
int lmax,rmax,sum;
abcd(int x=0)
{
lmax=rmax=max(x,0);
sum=x;
}
};
abcd operator + (const abcd &x,const abcd &y)
{
abcd z;
z.sum=x.sum+y.sum;
z.lmax=max(x.lmax,x.sum+y.lmax);
z.rmax=max(y.rmax,y.sum+x.rmax);
return z;
}
struct Tree{
Tree *ls,*rs;
abcd seq;
}*tree[M],mempool[M*20],*C=mempool;
int n,m,ans,a[M];
pair<int,int>b[M];
Tree* New_Node(Tree *_,Tree *__,abcd ___)
{
C->ls=_;
C->rs=__;
C->seq=___;
return C++;
}
Tree* Build_Tree(int x,int y)
{
int mid=x+y>>1;
if(x==y)
return New_Node( 0x0 , 0x0 , abcd(1) );
Tree *lson=Build_Tree(x,mid);
Tree *rson=Build_Tree(mid+1,y);
return New_Node(lson,rson,lson->seq+rson->seq);
}
Tree *Build_Chain(Tree *p,int x,int y,int z)
{
int mid=x+y>>1;
if(x==y)
return New_Node( 0x0 , 0x0 , abcd(-1) );
if(z<=mid)
{
Tree *lson=Build_Chain(p->ls,x,mid,z);
return New_Node(lson,p->rs,lson->seq+p->rs->seq);
}
else
{
Tree *rson=Build_Chain(p->rs,mid+1,y,z);
return New_Node(p->ls,rson,p->ls->seq+rson->seq);
}
}
abcd Get_Ans(Tree *p,int x,int y,int l,int r)
{
int mid=x+y>>1;
if(x==l&&y==r)
return p->seq;
if(r<=mid) return Get_Ans(p->ls,x,mid,l,r);
if(l>mid) return Get_Ans(p->rs,mid+1,y,l,r);
return Get_Ans(p->ls,x,mid,l,mid) + Get_Ans(p->rs,mid+1,y,mid+1,r);
}
bool Judge(int A,int B,int C,int D,int x)
{
int re=0;
re+=Get_Ans(tree[x],1,n,B,C).sum;
re+=Get_Ans(tree[x],1,n,A,B-1).rmax;
re+=Get_Ans(tree[x],1,n,C+1,D).lmax;
return re>=0;
}
int Bisection(int A,int B,int C,int D)
{
int l=1,r=n;
while(l+1<r)
{
int mid=l+r>>1;
if( Judge(A,B,C,D,mid) )
l=mid;
else
r=mid;
}
if( Judge(A,B,C,D,r) )
return r;
return l;
}
int main()
{
int i,j,q[10];
cin>>n;
for(i=1;i<=n;i++)
scanf("%d",&b[i].first),b[i].second=i;
sort(b+1,b+n+1);
for(i=1;i<=n;i++)
a[b[i].second]=i;
tree[1]=Build_Tree(1,n);
for(i=2;i<=n;i++)
tree[i]=Build_Chain(tree[i-1],1,n,b[i-1].second);
cin>>m;
for(i=1;i<=m;i++)
{
for(j=0;j<4;j++)
scanf("%d",&q[j]),q[j]=(q[j]+ans)%n+1;
sort(q,q+4);
printf("%d\n", ans=b[Bisection(q[0],q[1],q[2],q[3])].first );
}
}