给clj大爷跪了。。。。
反正题解网上都有。
注意这个二分然后赋值1/-1,然后判>=0的做法是个套路,仿佛比较常用?
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 20050 using namespace std; int n,m,a[maxn],q[4],lastans=0,x,y,z,w; int tot=0,root[maxn],ls[maxn*50],rs[maxn*50],l[maxn*50],r[maxn*50],sum[maxn*50]; struct data { int val,id; friend bool operator < (const data &x,const data &y) { return x.val<y.val; } }b[maxn]; struct status { int l,r,sum; status (int l,int r,int sum):l(l),r(r),sum(sum) {} status () {} }; void pushup(int now) { l[now]=max(l[ls[now]],sum[ls[now]]+l[rs[now]]); r[now]=max(r[rs[now]],sum[rs[now]]+r[ls[now]]); sum[now]=sum[ls[now]]+sum[rs[now]]; } void build(int &now,int left,int right) { now=++tot;l[now]=r[now]=sum[now]=right-left+1; if (left==right) return; int mid=(left+right)>>1; build(ls[now],left,mid); build(rs[now],mid+1,right); } void modify(int last,int &now,int left,int right,int pos) { now=++tot; if (left==right) {l[now]=r[now]=sum[now]=-1;return;} int mid=(left+right)>>1;ls[now]=ls[last];rs[now]=rs[last]; if (pos<=mid) modify(ls[last],ls[now],left,mid,pos); else modify(rs[last],rs[now],mid+1,right,pos); pushup(now); } status merge(status x,status y) { status ret; ret.l=max(x.l,x.sum+y.l); ret.r=max(y.r,y.sum+x.r); ret.sum=x.sum+y.sum; return ret; } status ask(int now,int left,int right,int lq,int rq) { if (lq>rq) return status(0,0,0); if (left==lq && right==rq) return status(l[now],r[now],sum[now]); int mid=(left+right)>>1; if (rq<=mid) return ask(ls[now],left,mid,lq,rq); else if (lq>=mid+1) return ask(rs[now],mid+1,right,lq,rq); else return merge(ask(ls[now],left,mid,lq,mid),ask(rs[now],mid+1,right,mid+1,rq)); } int binary_search() { int l=1,r=n,mid,ans; while (l<=r) { mid=(l+r)>>1; status k1=ask(root[mid],1,n,x,y),k2=ask(root[mid],1,n,y+1,z-1),k3=ask(root[mid],1,n,z,w); int ret=k1.r+k2.sum+k3.l; if (ret>=0) {ans=mid;l=mid+1;} else r=mid-1; } return ans; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) {scanf("%d",&a[i]);b[i].val=a[i];b[i].id=i;} sort(b+1,b+n+1); build(root[0],1,n);root[1]=root[0]; for (int i=2;i<=n;i++) modify(root[i-1],root[i],1,n,b[i-1].id); scanf("%d",&m); for (int i=1;i<=m;i++) { scanf("%d%d%d%d",&x,&y,&z,&w); x=(x+lastans)%n+1;y=(y+lastans)%n+1;z=(z+lastans)%n+1;w=(w+lastans)%n+1; q[0]=x;q[1]=y;q[2]=z;q[3]=w;sort(q,q+4); x=q[0];y=q[1];z=q[2];w=q[3]; lastans=b[binary_search()].val;printf("%d\n",lastans); } return 0; }