• [题解]luogu_P2824_HEOI2016排序(线段树/二分


    很难想,首先要二分答案,这样对于所有大于mid的数可以当做1,所有小于mid的可以当做0,这些1或0内部怎么排其实无所谓,然后1全放一边就可以,单调性的话比较好说,因为p点的数要么比mid大要么小,排列答案只会有一个

    #include<bits/stdc++.h>
    #define ls (x<<1)
    #define rs (x<<1|1)
    #define mid ((l+r)>>1)
    using namespace std;
    const int maxn=100009;
    int n,m,a[maxn],p,L[maxn],R[maxn],ch[maxn];
    struct node{
        int sum,tg;
    }t[maxn<<2];
    inline void upd(int x){
        t[x].sum=t[ls].sum+t[rs].sum;
    }
    inline void pd(int x,int l,int r){
        if(t[x].tg){
            t[ls].tg=t[x].tg;
            t[rs].tg=t[x].tg;
            if(t[x].tg==1){t[ls].sum=(mid-l+1);t[rs].sum=(r-mid);}
            else t[ls].sum=t[rs].sum=0;
            t[x].tg=0;
        }
    }
    void build(int x,int l,int r,int md){
        if(l==r){
            t[x].sum=(a[l]>=md);t[x].tg=0;
            return ;
        }
        build(ls,l,mid,md);build(rs,mid+1,r,md);
        upd(x);t[x].tg=0;
    }
    void change(int x,int l,int r,int L,int R,int val){
        if(L<=l&&r<=R){
            t[x].sum=val*(r-l+1);
            t[x].tg=val?1:-1;
            return;
        }
        pd(x,l,r);
        if(L<=mid)change(ls,l,mid,L,R,val);
        if(R>mid)change(rs,mid+1,r,L,R,val);
        upd(x);
    }
    int query(int x,int l,int r,int L,int R){
        if(L<=l&&r<=R)return t[x].sum;
        pd(x,l,r);
        int ans=0;
        if(L<=mid)ans+=query(ls,l,mid,L,R);
        if(R>mid)ans+=query(rs,mid+1,r,L,R);
        return ans;
    }
    int queryp(int x,int l,int r,int pos){
        if(l==r)return t[x].sum;
        pd(x,l,r);
        if(pos<=mid)return queryp(ls,l,mid,pos);
        else return queryp(rs,mid+1,r,pos);
    }
    bool check(int md){
        build(1,1,n,md);
        for(int i=1;i<=m;i++){
            int cnt1=query(1,1,n,L[i],R[i]);
            if(cnt1==0)continue;
            if(ch[i]==0){
                change(1,1,n,R[i]-cnt1+1,R[i],1);
                change(1,1,n,L[i],R[i]-cnt1,0);
            }
            else{
                change(1,1,n,L[i],L[i]+cnt1-1,1);
                change(1,1,n,L[i]+cnt1,R[i],0);
            }
        }
        return queryp(1,1,n,p);
    }
    int main(){
    //    freopen("4.in","r",stdin);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=m;i++)scanf("%d%d%d",&ch[i],&L[i],&R[i]);
        scanf("%d",&p);
        int LL=1,RR=n,ans;
        while(LL<=RR){
            int midd=(LL+RR)>>1;
            if(check(midd))ans=midd,LL=midd+1;
            else RR=midd-1;
        }
        printf("%d",ans);
    }
  • 相关阅读:
    java用户角色权限设计
    六种方式实现hibernate查询,及IDE推荐
    SSH远程会话管理工具
    Linux学习之CentOS(十三)--CentOS6.4下Mysql数据库的安装与配置
    Linux 下JDK安装
    linux下FTP的工具和使用以及rpmReadSignature failed错误
    不用FTP使用SecureCRT上传下载文件,并解决rz、sz command not found异常
    hibernate通过数据库表反向生成实体类
    解决vmware 桥联 再次使用联不上网的问题
    log4j详解与实战
  • 原文地址:https://www.cnblogs.com/superminivan/p/11737065.html
Copyright © 2020-2023  润新知