zoukankan      html  css  js  c++  java
  • 【Luogu】P2824排序(二分答案+线段树排序)

      题目链接

      震惊!两个线段树和一个线段树竟是50分的差距!

      本题可以使用二分答案,二分那个位置上最后是什么数。怎么验证呢?

      把原序列改变,大于等于mid的全部变成1,小于mid的全部变成0,之后线段树排序。

      最后看那个位置上是1还是0,若是1则说明最后那个位置上是个>=mid的数。

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #define left (rt<<1)
    #define right (rt<<1|1)
    #define mid ((l+r)>>1)
    #define lson l,mid,left
    #define rson mid+1,r,right
    #define maxn 300030
    using namespace std;
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    struct Que{
        int opt,from,to;
    }q[maxn];
    
    int d[maxn],w[maxn];
    
    int tree[maxn*4],mem[maxn*4],tag[maxn*4];
    inline void pushup(int rt){    tree[rt]=tree[left]+tree[right];    }
    inline void build(int l,int r,int rt){
        tree[rt]=mem[rt]=tag[rt]=0;
        if(l==r){
            tree[rt]=w[l];
            //printf("%d %d
    ",l,w[l]);
            return;
        }
        build(lson);
        build(rson);
        pushup(rt);
    }
    inline void pushdown(int rt,int m){
        if(mem[rt]==0&&tag[rt]==0)    return;
        if(mem[rt]){
            mem[left]=mem[right]=1;
            tree[left]=tree[right]=0;
            tag[left]=tag[right]=0;
            mem[rt]=0;
        }
        if(tag[rt]){
            tag[left]+=tag[rt];    tag[right]+=tag[rt];
            tree[left]+=m-(m>>1);
            tree[right]+=m>>1;
            tag[rt]=0;
        }
        return;
    }
    void update(int from,int to,int l,int r,int rt){
        if(from<=l&&to>=r){
            tag[rt]++;
            tree[rt]+=r-l+1;
            return;
        }
        pushdown(rt,r-l+1);
        if(from<=mid)    update(from,to,lson);
        if(to>mid)        update(from,to,rson);
        pushup(rt);
    }
    void memdate(int from,int to,int l,int r,int rt){
        if(from<=l&&to>=r){
            tag[rt]=0;    mem[rt]=1;
            tree[rt]=0;
            return;
        }
        pushdown(rt,r-l+1);
        if(from<=mid)    memdate(from,to,lson);
        if(to>mid)        memdate(from,to,rson);
        pushup(rt);
    }
    int query(int from,int to,int l,int r,int rt){
        if(from<=l&&to>=r)    return tree[rt];
        pushdown(rt,r-l+1);
        int ans=0;
        if(from<=mid)    ans+=query(from,to,lson);
        if(to>mid)        ans+=query(from,to,rson);
        return ans;
    }
    
    
    bool check(int lim,int n,int m,int last){
        build(1,n,1);
        for(int i=1;i<=m;++i){
            int opt=q[i].opt,from=q[i].from,to=q[i].to;
            int c1=query(from,to,1,n,1);
            int c2=to-from+1-c1;
            //printf("%d %d<<
    ",c1,c2);
            memdate(from,to,1,n,1);
            if(opt==0)    update(from+c2,to,1,n,1);
            else    update(from,from+c1-1,1,n,1);
        }
        //printf("zero
    ");
        //for(int i=1;i<=n;++i)    printf("%d ",zero.query(i,i,1,n,1));
        //printf("
    one
    ");
        //for(int i=1;i<=n;++i)    printf("%d ",one.query(i,i,1,n,1));
        //printf("
    ");
        return query(last,last,1,n,1);
    }
    
    int main(){
        int n=read(),m=read();
        for(int i=1;i<=n;++i)    d[i]=read();
        for(int i=1;i<=m;++i)    q[i]=(Que){read(),read(),read()};
        int last=read();
        int l=1,r=n,ans=0;
        while(l<=r){
            //printf("%d %d %d
    ",l,r,mid);
            for(int i=1;i<=n;++i)
                if(d[i]>=mid)    w[i]=1;
                else             w[i]=0;
            //for(int i=1;i<=n;++i)    printf("%d<",w[i]);
            //printf("
    ");
            if(check(mid,n,m,last)){
                ans=mid;
                l=mid+1;
            }
            else r=mid-1;
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    escape
    洛谷 P2158 【仪仗队】
    GIT学习----第五节:管理修改
    前端Webpack
    20 行 JS 代码,实现复制到剪贴板功能
    mysql表分区和分表的实现方式几种以及区别,什么时候用
    微信小程序----解析px、rpx、rem、vw实现页面布局
    微信小程序----相对路径图片不显示
    微信小程序----评价系统中的评星
    微信小程序----session_key失效导致的后台错误wxsp login api aesCbcUtil error info: pad block corrupted
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8855754.html
Copyright © 2011-2022 走看看