zoukankan      html  css  js  c++  java
  • BZOJ 4552 [Tjoi2016&Heoi2016]排序

    Description

    在2016年,佳媛姐姐喜欢上了数字序列。因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题
    ,需要你来帮助他。这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排
    序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q
    位置上的数字。

    Input

    输入数据的第一行为两个整数n和m。n表示序列的长度,m表示局部排序的次数。1 <= n, m <= 10^5第二行为n个整
    数,表示1到n的一个全排列。接下来输入m行,每一行有三个整数op, l, r, op为0代表升序排序,op为1代表降序
    排序, l, r 表示排序的区间。最后输入一个整数q,q表示排序完之后询问的位置, 1 <= q <= n。1 <= n <= 10^5
    ,1 <= m <= 10^5

    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

    这道题这是太神了,在zcg学长的推荐下写了这道题,思路就是二分答案和线段树进行验证,对于这颗线段树,每次二分的时候重新建树,每个叶子节点的值为a[pos]是否大于二分出来的那个数,如果大于等于的话为1,否则为0.那么操作0就代表把区间[l,r]里面的1全部放到这个区间的后面,而操作1则是放到前面,用线段树维护sum值再用lazy标记就好了

    code:

    #include <bits/stdc++.h>
    #define MAXN 100005
    using namespace std;
    int Judge,a[MAXN],n,m,p,Ans;
      
      
    template<typename _t>
    inline _t read(){
        _t x=0;
        int f=1;
        char ch=getchar();
        for(;ch>'9'||ch<'0';ch=getchar())if(ch=='-')f=-f;
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+(ch^48);
        return x*f;
    }
      
    struct node{
        node *ls,*rs;
        int sum,set,l,r;
      
        inline int __ls(){return ls?ls->sum:0;}
        inline int __rs(){return rs?rs->sum:0;}
      
        void Maintain(){
            sum=__ls()+__rs();
        }
      
        void push_down(){
            if(set==-1)return;
            int m=l+r>>1;
            if(ls){
                ls->set=set;
                ls->sum=(m-l+1)*set;
            }
            if(rs){
                rs->set=set;
                rs->sum=(r-m)*set;
            }
            set=-1;
        }
      
        node(){
            ls=rs=NULL;
            sum=0;set=-1;
        }
    }*root;
      
    void build(node *&o,int l,int r){
        if(!o)o=new node();
        o->l=l;o->r=r;
        o->set=-1;
        if(l==r){
            o->sum=(a[l]>=Judge);
            return;
        }
        int m=l+r>>1;
        build(o->ls,l,m);
        build(o->rs,m+1,r);
        o->Maintain();
    }
      
    void Update(node *o,int l,int r,int val){
        if(l>r)return;
        o->push_down();
        if(l<=o->l&&o->r<=r){
            o->set=val;
            o->sum=val*(o->r-o->l+1);
            return;
        }
        int m=o->l+o->r>>1;
        if(l<=m)Update(o->ls,l,r,val);
        if(m<r)Update(o->rs,l,r,val);
        o->Maintain();
    }
      
    int Query(node *o,int l,int r){
        o->push_down();
        if(l<=o->l&&o->r<=r)return o->sum;
        int m=o->l+o->r>>1,ans=0;
        if(l<=m)ans+=Query(o->ls,l,r);
        if(m<r)ans+=Query(o->rs,l,r);
        return ans;
    }
      
    struct Operation{
        int op,l,r;
        void init(){
            op=read<int>();
            l=read<int>();
            r=read<int>();
        }
    }c[MAXN];
      
    int main(){
        n=read<int>();m=read<int>();
        int maxn = -0x3f3f3f3f;
        for(int i=1;i<=n;i++)a[i]=read<int>(),maxn=max(maxn,a[i]);
        for(int i=1;i<=m;i++)c[i].init();
        p=read<int>();
        int l=1,r=maxn;
        while(l<=r){
            Judge=l+r>>1;
            build(root,1,n);
            for(int i=1;i<=m;i++){
                if(c[i].op==0){
                    int sum = Query(root,c[i].l,c[i].r);
                    Update(root,c[i].r-sum+1,c[i].r,1);
                    Update(root,c[i].l,c[i].r-sum,0);
                }
                else{
                    int sum = Query(root,c[i].l,c[i].r);
                    Update(root,c[i].l+sum,c[i].r,0);
                    Update(root,c[i].l,c[i].l+sum-1,1);
                }
            }
            int ans = Query(root,p,p);
            if(ans)Ans=Judge,l=Judge+1;
            else r=Judge-1;
        }
        printf("%d
    ",Ans);
    }



  • 相关阅读:
    JS 集合
    JS 字典
    JS 链表
    JS 队列
    JS 栈
    JS 列表
    JS 数组
    IOS 提示无法下载程式问题
    ubuntu 下安装Go开发环境
    菜鸟看Redis(一)
  • 原文地址:https://www.cnblogs.com/Cooook/p/7738512.html
Copyright © 2011-2022 走看看