记录编号 446182 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2012]middle 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 5.701 s
提交时间 2017-09-07 19:45:47 内存使用 382.90 MiB
显示代码纯文本
//二分答案,若改位数值>=ans,则为1,否则为0;
//若最大子区间和>=0则合法
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e5+10,M=2e7+10;
struct node{int l,r,sum,maxl,maxr;}nd[M];
int root[N],id=3;//root[i]表示>=a[i+1]的线段树
#define lc nd[x].l
#define rc nd[x].r
void update(int x){
    nd[x].sum=nd[lc].sum+nd[rc].sum;
    nd[x].maxl=max(nd[lc].maxl,nd[lc].sum+nd[rc].maxl);
    nd[x].maxr=max(nd[rc].maxr,nd[rc].sum+nd[lc].maxr);
}
int add(int x,int l,int r,int p,int d){
    int now=++id;
    nd[now]=nd[x];
    if (l==r){
        nd[now].sum+=d;
        nd[now].maxl=nd[now].maxr=max(nd[now].sum,0);
        return now;
    }
    int mid=(l+r)>>1;
    if (p>mid) nd[now].r=add(rc,mid+1,r,p,d);
        else nd[now].l=add(lc,l,mid,p,d);
    update(now);
    return now;
}
void query(int x,int l,int r,int L,int R){
    if (l>=L&&r<=R){
        nd[2]=nd[1];nd[3]=nd[x];
        nd[1].l=2;nd[1].r=3;
        update(1);
        return;
    }
    int mid=(l+r)>>1;
    if (L<=mid) query(lc,l,mid,L,R);
    if (R>mid) query(rc,mid+1,r,L,R);
}
int n,Q,a[N],sa[N];
bool cmp(int x,int y){return a[x]<a[y];}
bool test(int rt,int a,int b,int c,int d){
    nd[1]=(node){0,0,0,0,0};
    query(rt,1,n,b,c);
    int sum=nd[1].sum;
    //printf("[%d,%d] sum=%d\n",b,c,sum);
    nd[1]=(node){0,0,0,0,0};
    query(rt,1,n,a,b-1);
    sum+=nd[1].maxr;
    nd[1]=(node){0,0,0,0,0};
    query(rt,1,n,c+1,d);
    sum+=nd[1].maxl;
    //printf("%d\n",sum);
    return sum>=0;
}
int query(int a,int b,int c,int d){
    int l=1,r=n;
    while (l<r){
        int mid=(l+r)>>1;
        //printf("query(>=%d)=",::a[sa[mid+1]]);
        if (test(root[mid],a,b,c,d)) l=mid+1;else r=mid;
    }
    return ::a[sa[l]];
}
int main()
{
    freopen("nt2012_middle.in","r",stdin);
    freopen("nt2012_middle.out","w",stdout);
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]),sa[i]=i;
    sort(sa+1,sa+n+1,cmp);
    for (int i=1;i<=n;i++) root[0]=add(root[0],1,n,i,1);
    for (int i=1;i<=n;i++) root[i]=add(root[i-1],1,n,sa[i],-2);
    scanf("%d",&Q);
    int ans=0,q[10];
    while (Q--){
        for (int i=0;i<4;i++) scanf("%d",&q[i]),q[i]=(q[i]+ans)%n+1;
        sort(q,q+4);
        //for (int i=0;i<4;i++) printf("%d ",q[i]);puts("");
        printf("%d\n",ans=query(q[0],q[1],q[2],q[3]));
    }
    return 0;
}