新姿势
注意区间的合并问题,比如最大前缀和最大后缀的合并,表示被这里卡了好长时间
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<utility>
#define fi first
#define se second
#define MK(a,b) make_pair((a),(b))
#define pii pair<int,int>
using namespace std;
const int N=20005;
int n,m;
int val[N],to[N],rt[N];
pii b[N];
int tot;
struct aa
{
int l,r,lc,rc,sum,qz,hz;
int len(){return r-l+1;}
}a[N*30];
void up(int u)
{
int l=a[u].lc,r=a[u].rc;
a[u].sum=a[l].sum+a[r].sum;
a[u].qz=max(a[l].sum+a[r].qz,a[l].qz);
a[u].hz=max(a[r].sum+a[l].hz,a[r].hz);
}
void build(int &u,int l,int r)
{
u=++tot;
a[u].l=l,a[u].r=r;
if (l==r)
{
a[u].sum=a[u].qz=a[u].hz=1;
return ;
}
int mid=(l+r)>>1;
build(a[u].lc,l,mid);
build(a[u].rc,mid+1,r);
up(u);
}
void insert(int old,int &now,int pos)
{
now=++tot;a[now]=a[old];
if (a[old].l==a[old].r)
{
a[now].sum=-1;
a[now].qz=a[now].hz=0;
return ;
}
int mid=(a[old].l+a[old].r)>>1;
if (pos<=mid) insert(a[old].lc,a[now].lc,pos);
else insert(a[old].rc,a[now].rc,pos);
up(now);
}
void init()
{
sort(b,b+n);
build(rt[0],0,n-1);
for (int i=1;i<n;i++) insert(rt[i-1],rt[i],b[i-1].se);
}
int find_sum(int u,int l,int r)
{
if (a[u].l==l&&a[u].r==r) return a[u].sum;
int mid=(a[u].l+a[u].r)>>1;
if (r<=mid) return find_sum(a[u].lc,l,r);
if (mid<l) return find_sum(a[u].rc,l,r);
return find_sum(a[u].lc,l,mid)+find_sum(a[u].rc,mid+1,r);
}
int find_qz(int u,int l,int r)
{
if (l>r) return 0;
if (a[u].l==l&&a[u].r==r) return a[u].qz;
int mid=(a[u].l+a[u].r)>>1;
if (r<=mid) return find_qz(a[u].lc,l,r);
if (mid<l) return find_qz(a[u].rc,l,r);
return max(find_sum(a[u].lc,l,mid)+find_qz(a[u].rc,mid+1,r),find_qz(a[u].lc,l,mid));
}
int find_hz(int u,int l,int r)
{
if (l>r) return 0;
if (a[u].l==l&&a[u].r==r) return a[u].hz;
int mid=(a[u].l+a[u].r)>>1;
if (r<=mid) return find_hz(a[u].lc,l,r);
if (mid<l) return find_hz(a[u].rc,l,r);
return max(find_sum(a[u].rc,mid+1,r)+find_hz(a[u].lc,l,mid),find_hz(a[u].rc,mid+1,r));
}
int pan(int mid,int *q)
{
return find_sum(rt[mid],q[1],q[2])+find_hz(rt[mid],q[0],q[1]-1)+find_qz(rt[mid],q[2]+1,q[3]);
}
void work(int *q,int &x)
{
int l=0,r=n-1,ans=0,mid;
while (l<=r)
{
mid=(l+r)>>1;
if (pan(mid,q)>=0) ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d\n",b[ans].fi);x=b[ans].fi;
}
int main()
{
scanf("%d",&n);
for (int i=0;i<n;i++) scanf("%d",&val[i]),b[i]=MK(val[i],i);
init();
int x=0,q[4];
scanf("%d",&m);
while (m--)
{
scanf("%d%d%d%d",&q[0],&q[1],&q[2],&q[3]);
for (int i=0;i<4;i++) q[i]=(q[i]+x)%n;
sort(q,q+4);
work(q,x);
}
return 0;
}