• [bzoj4552][Tjoi2016][Heoi2016]排序


    Description

    给出一个$1$到$n$的全排列,现在对这个全排列序列进行$m$次局部排序,排序分为$2$种:

    $1.(0,l,r)$表示将区间$[l,r]$的数字升序排序;

    $2.(1,l,r)$表示将区间$[l,r]$的数字降序排序.

    最后询问第$q$位置上的数字.

    Input

    第$1$行为两个整数$n$和$m$.$n$表示序列的长度,$m$表示局部排序的次数.

    第$2$行为$n$个整数,表示$1$到$n$的一个全排列.

    接下来输入$m$行,每$1$行有$3$个整数$op,l,r$.

    $op$为$0$代表升序排序,$op$为$1$代表降序排序;$l,r$表示排序的区间.

    最后输入一个整数$q$,$q$表示排序完之后询问的位置.

    Output

    输出数据仅有一行一个整数,表示按照顺序将全部的部分排序结束后第$q$位置上的数字.

    Sample Input

    6 3
    1 6 2 5 3 4
    0 1 4
    1 3 6
    0 2 4
    3

    Sample Output

    5

    HINT

    $1;leq;n,m;leq;10^5,1;leq;q;leq;n.$

    Solution

    二分答案$ans$.

    把$;leq;ans$的位置标为$1$,其余标为$0$.

    线段树维护排序操作,最后判断位置$q$上是否为$0$.

    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define N 100005
    #define M 300005
    using namespace std;
    struct linetree{
        int l,r,t,op;
    }lt[M];
    struct quest{
        int op,l,r;
    }b[N];
    int a[N],n,m,q,t,l,r,mid;
    inline void build(int u,int l,int r,int k){
        lt[u].l=l;lt[u].r=r;lt[u].op=0;
        if(lt[u].l<lt[u].r){
            int lef=u<<1,rig=u<<1|1;
            int mid=(lt[u].l+lt[u].r)>>1; 
            build(lef,l,mid,k);build(rig,mid+1,r,k);
            lt[u].t=lt[lef].t+lt[rig].t;
        }
        else if(a[lt[u].l]>=k) lt[u].t=0;
        else lt[u].t=1;
    }
    inline void cover(int u,int i){
        if(lt[u].l>=b[i].l&&lt[u].r<=b[i].r){
            if(!b[i].op){
                lt[u].op=-1;
                if(lt[u].l-b[i].l+1<=t){
                    lt[u].t=min(t-(lt[u].l-b[i].l),lt[u].r-lt[u].l+1);
                }
                else lt[u].t=0;
            }
            else{
                lt[u].op=1;
                if(b[i].r-lt[u].r+1<=t){
                    lt[u].t=min(t-(b[i].r-lt[u].r),lt[u].r-lt[u].l+1);
                }
                else lt[u].t=0;
            }
        }
        else if(lt[u].l<lt[u].r){
            int lef=u<<1,rig=u<<1|1;
            int mid=(lt[u].l+lt[u].r)>>1;
            if(lt[u].op>0)/*降序*/{
                lt[u].op=0;lt[lef].op=lt[rig].op=1;
                lt[rig].t=min(lt[u].t,lt[rig].r-lt[rig].l+1);
                lt[lef].t=lt[u].t-lt[rig].t;
            }
            else if(lt[u].op<0)/*升序*/{
                lt[u].op=0;lt[lef].op=lt[rig].op=-1;
                lt[lef].t=min(lt[u].t,lt[lef].r-lt[lef].l+1);
                lt[rig].t=lt[u].t-lt[lef].t;
            }
            if(b[i].l<=mid) cover(lef,i);
            if(b[i].r>mid) cover(rig,i);
            lt[u].t=lt[lef].t+lt[rig].t;
        }
    }
    inline int ask(int u,int l,int r){
        if(lt[u].l>=l&&lt[u].r<=r)
            return lt[u].t;
        if(lt[u].l<lt[u].r){
            int lef=u<<1,rig=u<<1|1,ret=0;
            int mid=(lt[u].l+lt[u].r)>>1;
            if(lt[u].op>0)/*降序*/{
                lt[u].op=0;lt[lef].op=lt[rig].op=1;
                lt[rig].t=min(lt[u].t,lt[rig].r-lt[rig].l+1);
                lt[lef].t=lt[u].t-lt[rig].t;
            }
            else if(lt[u].op<0)/*升序*/{
                lt[u].op=0;lt[lef].op=lt[rig].op=-1;
                lt[lef].t=min(lt[u].t,lt[lef].r-lt[lef].l+1);
                lt[rig].t=lt[u].t-lt[lef].t;
            }
            if(l<=mid) ret+=ask(lef,l,r);
            if(r>mid) ret+=ask(rig,l,r);
            return ret;
        }
    }
    inline bool chk(int k){
        build(1,1,n,k);
        for(int i=1;i<=m;++i){
            t=ask(1,b[i].l,b[i].r);cover(1,i);
        }
        return !ask(1,q,q);
    }
    inline void init(){
        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",&b[i].op,&b[i].l,&b[i].r);
        scanf("%d",&q);
        l=1;r=n;
        while(l<r){
            mid=(l+r+1)>>1;
            if(chk(mid)) l=mid;
            else r=mid-1;
        } 
        printf("%d
    ",l);
    }
    int main(){
        freopen("sort.in","r",stdin);
        freopen("sort.out","w",stdout);
        init();
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
  • 相关阅读:
    11计划
    Tomcat Server.xml配置详解
    maven常用配置
    [转]Maven的内置属性说明
    PL/SQL Developer使用技巧、快捷键
    01_jeecms建站
    01_bootStrap中Tab页签切换
    利用Java实现文件中的关键字查询
    SVN服务器搭建
    MyEclipse安装插件的几种方法
  • 原文地址:https://www.cnblogs.com/AireenYe/p/6218773.html
Copyright © 2020-2023  润新知