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

    LuoguP2824 [HEOI2016/TJOI2016]排序

    题目

    连接

    题解

    考虑对一个0,1区间排序,显然线段树可以很容易做到

    现在我们询问第Q个位置的值:我们可以考虑二分答案,将大于Q的答案设为1,将小于Q的答案设为0

    显然当当前二分答案的值大于实际值,第Q个位置的值一定为1,所以可以二分

    #include<bits/stdc++.h>
    
    using namespace std;
     
    #define ll long long
    #define re register
     
    inline ll read()
    {
        ll f = 1,x = 0;
        char ch;
        do
        {
            ch = getchar();
            if(ch == '-') f = -1;
        }while(ch<'0'||ch>'9');
        do
        {
            x = (x<<3) + (x<<1) + ch - '0';
            ch = getchar();
        }while(ch>='0'&&ch<='9');
        return f*x;
    }
    
    const int MAXN = 1e5 + 10;
    
    #define lc o<<1
    #define rc o<<1|1
    
    int n,m,q;
    int a[MAXN];
    int ans;
    int add[MAXN<<2],sum[MAXN<<2];
    int opt[MAXN],l[MAXN],r[MAXN];
    
    inline void build(int o,int l,int r,int v)
    {
        if(l == r)
        {
            sum[o] = (a[l]>=v);add[o]=0;return;
        }
        int mid = (l+r)>>1;
        build(lc,l,mid,v);
        build(rc,mid+1,r,v);
        sum[o]=sum[lc]+sum[rc];add[o]=0;
    }
    
    inline void pushdown(int o,int l,int r)
    {
        if(!add[o]) return;
        int mid = (l+r)>>1;
        add[lc]=add[rc]=add[o];
        if(add[o]==1)
        {
            sum[lc]=mid-l+1;
            sum[rc]=r-mid;
        }
        else
        {
            sum[lc]=sum[rc]=0;
        }
        add[o]=0;
    }
    
    inline void update(int o,int l,int r,int x,int y,int v)
    {
        if(x<=l&&y>=r)
        {
            sum[o]=v*(r-l+1);
            if(v==1) add[o]=1;
            else add[o]=-1;
            return;
        }
        if(l>y||x>r) return;
        pushdown(o,l,r);
        int mid = (l+r)>>1;
        update(lc,l,mid,x,y,v);
        update(rc,mid+1,r,x,y,v);
        sum[o]=sum[lc]+sum[rc];
    }
    
    inline int query(int o,int l,int r,int x,int y)
    {
        if(x<=l&&y>=r) return sum[o];
        if(l>y||r<x) return 0;
        int mid = (l+r)>>1;
        pushdown(o,l,r);
        return query(lc,l,mid,x,y)+query(rc,mid+1,r,x,y);
    }
    
    inline int query2(int o,int l,int r,int p)
    {
        if(l==r&&l==p) return sum[o];
        int mid = (l+r)>>1;
        pushdown(o,l,r);
        if(mid>=p) return query2(lc,l,mid,p);
        return query2(rc,mid+1,r,p);
    }
    
    inline bool check(int x)
    {
        build(1,1,n,x);
    
        for(int i=1;i<=m;i++)
        {    
            int res = query(1,1,n,l[i],r[i]);
            if(opt[i]==0)
            {
                update(1,1,n,r[i]-res+1,r[i],1);
                update(1,1,n,l[i],r[i]-res,0);
            }
            else
            {
                update(1,1,n,l[i]+res,r[i],0);
                update(1,1,n,l[i],l[i]+res-1,1);
            }
        }
        return query2(1,1,n,q);
    }
    
    int main()
    {
        n = read(),m = read();
        for(int i=1;i<=n;i++) a[i] = read();
        for(int i=1;i<=m;i++) opt[i]=read(),l[i]=read(),r[i]=read();
        q=read();
        int l = 1,r = n;
        while(l <= r)
        {
            int mid = (l + r) >> 1;
            if(check(mid))
            {
                //cout << mid << endl;
                ans = mid;
                l = mid + 1;
            }
            else r = mid - 1;
        }
        cout << ans << endl;
    }
  • 相关阅读:
    ES基本介绍
    Mybatis 读写分离简单实现
    分享一个Flink checkpoint失败的问题和解决办法
    一次“内存泄露”引发的血案
    记一次堆外内存泄漏排查过程
    MySQL主从复制读写分离,看这篇就够了!
    JVM运行时内存数据区域
    .NET MVC 页面传值方式
    jQuery 对表格内容进行搜索筛选
    泛型
  • 原文地址:https://www.cnblogs.com/wlzs1432/p/12031295.html
Copyright © 2011-2022 走看看