首页 > 其他 > 详细

hdu6278(二分主席树,求区间中最大的x,满足大于等于x的数量大于等于x)

时间:2020-09-18 15:40:07      阅读:73      评论:0      收藏:0      [点我收藏+]

题: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\n",ans);
        }
        t1.Clear(t1.cnt);

    }
    return 0;
}
View Code

 

hdu6278(二分主席树,求区间中最大的x,满足大于等于x的数量大于等于x)

原文:https://www.cnblogs.com/starve/p/13691269.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!