zoukankan      html  css  js  c++  java
  • hdu6278(二分主席树,求区间中最大的x,满足大于等于x的数量大于等于x)

    题:http://acm.hdu.edu.cn/showproblem.php?pid=6278

    题意:求区间中最大的x,满足大于等于x的数量大于等于x

    分析:二分找答案,check(mid)为查询区间中第len-mid+1大的数是否大于mid

    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    #define MP make_pair
    #define lson root<<1,l,midd
    #define rson root<<1|1,midd+1,r
    typedef long long ll;
    const int mod=10007;
    const int M=2e5+5;
    const int inf=0x3f3f3f3f;
    const ll INF=1e18;
    int a[M],b[M];
    struct ChairTree{
        int root[M],cnt;
        struct node{
            int sum,L,R;
        }tr[M*40];
        void Clear(int n){
            for(int i=0;i<=n;i++)
                tr[i].sum=tr[i].L=tr[i].R=0;
        }
        void update(int &rt,int pos,int l,int r){
            tr[++cnt]=tr[rt];
            tr[cnt].sum++;
            rt=cnt;
            if(l==r)
                return;
            int midd=(l+r)>>1;
            if(pos<=midd)
                update(tr[rt].L,pos,l,midd);
            else
                update(tr[rt].R,pos,midd+1,r);
        }
        int query(int i,int j,int k,int l,int r){
            int num=tr[tr[j].L].sum-tr[tr[i].L].sum;
            if(l==r)
                return l;
            int midd=(l+r)>>1;
            if(num>=k)
                return query(tr[i].L,tr[j].L,k,l,midd);
            else
                return query(tr[i].R,tr[j].R,k-num,midd+1,r);
        }
    }t1;
    int main(){
        int n,m;
        while(~scanf("%d%d",&n,&m)){
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]),b[i]=a[i];
            sort(b+1,b+1+n);
            int p=unique(b+1,b+1+n)-b-1;
            t1.cnt=0;
            for(int i=1;i<=n;i++){
                t1.root[i]=t1.root[i-1];
                int pos=lower_bound(b+1,b+1+p,a[i])-b;
                t1.update(t1.root[i],pos,1,p);
            }
            while(m--){
                int x,y;
                scanf("%d%d",&x,&y);
                int len=y-x+1;
                int l=0,r=len,ans=0;
                while(l<=r){
                    int midd=(l+r)>>1;
                    if(b[t1.query(t1.root[x-1],t1.root[y],len-midd+1,1,p)]>=midd){
                        ans=max(ans,midd);
                        l=midd+1;
                    }
                    else
                        r=midd-1;
                }
                printf("%d
    ",ans);
            }
            t1.Clear(t1.cnt);
    
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Hacking Tools
    SDN 网络系统之 Mininet 与 API 详解
    Rust安装配置
    研华 FWA-3231 单路E3平台
    Netscaler Configuration Architecture
    TCP拥塞控制算法纵横谈-Illinois和YeAH
    TCP协议疑难杂症全景解析
    Windows WMIC命令使用详解(附实例)
    Windows一个文件夹下面最多可以放多少文件
    喝酒游戏,概率分布和卷积
  • 原文地址:https://www.cnblogs.com/starve/p/13691269.html
Copyright © 2011-2022 走看看