BZOJ 2653 middle

Posted on 2017-03-08 20:38  ziliuziliu  阅读(91)  评论(0编辑  收藏  举报

给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;
}