1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| #include <bits/stdc++.h> #define MAXN 20005 using namespace std; inline int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=(x<<3)+(x<<1)+(ch^'0'); ch=getchar(); } return x*f; } namespace SegmentTree{ struct node{ int l,r; int lmax,rmax,sum; }tree[MAXN*20]; int tot; #define lc tree[i].l #define rc tree[i].r node operator + (node A,node B){ node C; C.sum=A.sum+B.sum; C.lmax=max(A.lmax,A.sum+B.lmax); C.rmax=max(B.rmax,A.rmax+B.sum); return C; } void pushup(int i){ tree[i].sum=tree[lc].sum+tree[rc].sum; tree[i].lmax=max(tree[lc].lmax,tree[lc].sum+tree[rc].lmax); tree[i].rmax=max(tree[rc].rmax,tree[lc].rmax+tree[rc].sum); } inline void Value(int i,int val){ tree[i].sum=tree[i].lmax=tree[i].rmax=val; } void build(int &i,int L,int R){ if (!i) i=++tot; Value(i,R-L+1); if (L==R){ return ; } int mid=(L+R)>>1; build(lc,L,mid); build(rc,mid+1,R); pushup(i); } void update(int &i,int L,int R,int index){ tree[++tot]=tree[i],i=tot; if (L==R) { Value(i,-1); return ; } int mid=(L+R)>>1; if (index<=mid) update(lc,L,mid,index); else update(rc,mid+1,R,index); pushup(i); } node query(int i,int L,int R,int ql,int qr){ if (ql<=L&&R<=qr){ return tree[i]; } int mid=(L+R)>>1; if (ql>mid) return query(rc,mid+1,R,ql,qr); else if (qr<=mid) return query(lc,L,mid,ql,qr); else return query(lc,L,mid,ql,qr)+query(rc,mid+1,R,ql,qr); } } using namespace SegmentTree; int rt[MAXN]; int a[MAXN],b[MAXN],c[MAXN]; inline bool cmp(int A,int B){ return a[A]<a[B]; } inline void discrete(int n){ for (register int i=1;i<=n;++i) b[i]=i; sort(b+1,b+1+n,cmp); } int n; #define VAR rt[mid],1,n inline int Check(int mid,int A,int B,int C,int D){ int sum=0; if (B+1<=C-1) sum+=query(VAR,B+1,C-1).sum; sum+=query(VAR,A,B).rmax; sum+=query(VAR,C,D).lmax; return sum; } int p[4]; int main(){ n=read(); for (register int i=1;i<=n;++i) a[i]=read(); discrete(n); build(rt[1],1,n); for (register int i=2;i<=n;++i){ rt[i]=rt[i-1]; update(rt[i],1,n,b[i-1]); } int last=0; int q=read(); while (q--){ for (register int i=0;i<4;++i){ p[i]=(read()+last)%n+1; } sort(p,p+4); int A=p[0],B=p[1],C=p[2],D=p[3]; int l=1,r=n; int ans=0; while (l<=r){ int mid=(l+r)>>1; if (Check(mid,A,B,C,D)>=0) { ans=a[b[mid]]; l=mid+1; } else { r=mid-1; } } last=ans; printf("%d\n",ans); } }
|