zoukankan      html  css  js  c++  java
  • P2824 [HEOI2016/TJOI2016]排序

    链接:Miku

    ----------------------------

    一道二分+线段树

    -----------------------------

    显然暴力模拟会T飞,可以用二分解决

    -----------------------------

    二分啥呢?二分mid与最后在q的位置的数的大小

    但是怎么知道大还是小呢,既然我们只想要知道大还是小,那么那个点原来是

    多大/多小是没有意义的,只有和mid的相对大小,那么我们就把比mid大的改成1,小于等于的改为0

    然后进行排序

    这样仅仅是不行的,对于排序,因为已经变成了0和1,那么我们只要知道区间1的个数就行了,然后把1都放到最前面/最后面即可

    这个查询和修改可以用线段树来实现

    ----------------------------------

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n;
    int m;
    int l,r;
    int mid;
    int a[100005];
    int b[100005];
    int sum[400005];
    int lazy[400005];
    int q;
    int f;
    struct ch{
        int l;
        int r;
        int f;
    }change[100005];
    void pushup(int x){
        sum[x]=sum[x<<1]+sum[x<<1|1];
    }
    void pushdown(int x,int l,int r){
        if(lazy[x]!=-1){
            int mid=(l+r)>>1;
            lazy[x<<1]=lazy[x];
            lazy[x<<1|1]=lazy[x];
            sum[x<<1]=lazy[x]*(mid-l+1);
            sum[x<<1|1]=lazy[x]*(r-mid);
            lazy[x]=-1;
            return ;
        }
        return ;
    }
    void update(int x,int l,int r,int L,int R,int d){
        if (L > R) return;
        if(L<=l&&r<=R){
            sum[x]=d*(r-l+1);
            lazy[x]=d;
            return ;
        }
        pushdown(x,l,r);
        int mid=(l+r)>>1;
        if(L<=mid) update(x<<1,l,mid,L,R,d);
        if(R>mid)  update(x<<1|1,mid+1,r,L,R,d);
        pushup(x); 
    }
    int query(int x,int l,int r,int L,int R){
        if(L<=l&&r<=R){
            return sum[x];
        }
        pushdown(x,l,r);
        int mid=(l+r)>>1;
        int ans=0;
        if(L<=mid) ans+=query(x<<1,l,mid,L,R);
        if(R>mid) ans+=query(x<<1|1,mid+1,r,L,R);
        return ans;
    }
    bool check(int k){
        for(int i=1;i<=4*n;++i){//每一次都要初始化 
        lazy[i]=-1;
        sum[i]=0;
        }
        for(int i=1;i<=n;++i){
            if(a[i]>=k){
                update(1,1,n,i,i,1);//初始化 
            }
        }
        for(int i=1;i<=m;++i){
            if(change[i].f==0){
                int cnt=query(1,1,n,change[i].l,change[i].r);//只有0,1的排序 
                update(1,1,n,change[i].r-cnt+1,change[i].r,1);
                update(1,1,n,change[i].l,change[i].r-cnt,0);
            }
            else{
                int cnt=query(1,1,n,change[i].l,change[i].r);
                update(1,1,n,change[i].l+cnt,change[i].r,0);
                update(1,1,n,change[i].l,change[i].l+cnt-1,1);
            }
        }
        if(query(1,1,n,q,q)){//查询一下大了还是小了 
            return 1;
        }
        return 0;
    }
    int main(){
        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",&change[i].f,&change[i].l,&change[i].r);
        }
        scanf("%d",&q);
        l=1;//l永远成立 
        r=n+1;//r永不成立 
        while(r-l>1){//当然要小于1最后 
            mid=(l+r)>>1;
            if(check(mid)){
                l = mid;
            }
            else{
                r =  mid;
            }
        }
        cout<<l;
        return 0;
    }
    Ac
  • 相关阅读:
    mysql导sql脚本
    oracle导sql脚本
    基于jdk proxy的动态代理模式
    vue组件之组件的生命周期
    vue组件之组件间的通信
    python-爬虫scrapy框架安装及基本使用
    mongdb的使用
    python-爬虫 多线程爬虫
    python-爬虫 爬虫利器BeautifulSoup
    python-爬虫lxml库
  • 原文地址:https://www.cnblogs.com/For-Miku/p/12384468.html
Copyright © 2011-2022 走看看