bzoj4552

二分在q位置上的数。其他数若大于它,则为1,否则为0,最后若该位上的数为0,则区间右移l,否则左移r

check过程中用线段树维护,降序升序可以用区间复制实现

#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
const int N=100005;
int n,m,q,tr[4*N],laz[4*N],a[N],typ[N],ql[N],qr[N],val[N];

inline int read(){
    char ch=getchar();int k=0,f=1;
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){k=(k<<1)+(k<<3)+ch-'0';ch=getchar();}
    return k*f;
}

void buildtr(int now,int l,int r){
    laz[now]=0;
    if(l==r){tr[now]=val[l];return;}
    int mid=(l+r)>>1;
    buildtr(now<<1,l,mid);buildtr(now<<1|1,mid+1,r);
    tr[now]=tr[now<<1]+tr[now<<1|1];
}

void pushdown(int now,int l,int r){
    if(laz[now]==0)return;
    int mid=(l+r)>>1;
    if(laz[now]==1){
        laz[now<<1]=laz[now<<1|1]=1;laz[now]=0;
        tr[now<<1]=mid-l+1;tr[now<<1|1]=r-mid;
    }else
    if(laz[now]==-1){
        laz[now<<1]=laz[now<<1|1]=-1;laz[now]=0;
        tr[now<<1]=tr[now<<1|1]=0;
    }
}

void change(int now,int l,int r,int L,int R,int v){
    if(l>=L&&r<=R){
        if(v==1){laz[now]=1;tr[now]=r-l+1;}else{laz[now]=-1;tr[now]=0;}
        return;
    }
    pushdown(now,l,r);
    int mid=(l+r)>>1;
    if(mid>=L)change(now<<1,l,mid,L,R,v);
    if(mid<R)change(now<<1|1,mid+1,r,L,R,v);
    tr[now]=tr[now<<1]+tr[now<<1|1];
}

int query(int now,int l,int r,int L,int R){
    if(l>=L&&r<=R)return tr[now];
    pushdown(now,l,r);
    int mid=(l+r)>>1,res=0;
    if(mid>=L)res+=query(now<<1,l,mid,L,R);
    if(mid<R)res+=query(now<<1|1,mid+1,r,L,R);
    return res;
}

void Putans(int x){
    if(x>=10)Putans(x/10);putchar(x%10+'0');
}

int main(){
    n=read();m=read();
    for(int i=1;i<=n;i++)a[i]=read();
    for(int i=1;i<=m;i++){typ[i]=read();ql[i]=read();qr[i]=read();if(ql[i]>qr[i])swap(ql[i],qr[i]);}
    q=read();
    int l=1,r=n;
    while(l<r){
        int mid=(l+r)>>1;
        for(int i=1;i<=n;i++)val[i]=a[i]>mid?1:0;
        buildtr(1,1,n);
        for(int i=1;i<=m;i++){
            int cnt=query(1,1,n,ql[i],qr[i]);
            if(typ[i]==0){
                if(cnt>0&&cnt<qr[i]-ql[i]+1)change(1,1,n,qr[i]-cnt+1,qr[i],1);
                if(qr[i]-cnt>=ql[i]&&cnt>0)change(1,1,n,ql[i],qr[i]-cnt,0);
            }
            else{
                if(cnt>0&&cnt<qr[i]-ql[i]+1)change(1,1,n,ql[i],ql[i]+cnt-1,1);
                if(ql[i]+cnt<=qr[i]&&cnt>0)change(1,1,n,ql[i]+cnt,qr[i],0);
            }
        }
        if(query(1,1,n,q,q))l=mid+1;else r=mid;
    }
    Putans(l);
}

 

posted @ 2018-04-20 09:40  lnyzo  阅读(125)  评论(0编辑  收藏  举报