HDU-6287:Just h-index(二分+主席树)

Just h-index

                                                              Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)
                                                                                       Total Submission(s): 83    Accepted Submission(s): 48


Problem Description
The  h-index of an author is the largest  h where he has at least  h papers with citations not less than  h.

Bobo has published  n papers with citations  a1,a2,,an respectively.
One day, he raises  q questions. The  i-th question is described by two integers  li and  ri, asking the  h-index of Bobo if has *only* published papers with citations  ali,ali+1,,ari.
 

Input
The input consists of several test cases and is terminated by end-of-file.

The first line of each test case contains two integers  n and  q.
The second line contains  n integers  a1,a2,,an.
The  i-th of last  q lines contains two integers  li and  ri.
 

Output
For each question, print an integer which denotes the answer.

## Constraint

1n,q105
1ain
1lirin
* The sum of  n does not exceed  250,000.
* The sum of  q does not exceed  250,000.
 

Sample Input
 
   
5 3 1 5 3 2 1 1 3 2 4 1 5 5 1 1 2 3 4 5 1 5
 

Sample Output
 
   
2 2 2 3

思路:二分枚举h,利用主席树求[L,R]区间内是否满足有至少h个数大于等于h。

#include
using namespace std;
const int MAX=1e5+10;
const int MOD=1e9+7;
const double PI=acos(-1.0);
typedef long long ll;
int a[MAX];
vectorv;
struct lenka
{
    int L,R,sum;
}A[40*MAX];
int tot,root[MAX];
void init()
{
    tot=1;
    root[0]=0;
    A[0].sum=A[0].L=A[0].R=0;
    v.clear();
}
void build(int x,int& rt,int l,int r)
{
    A[tot++]=A[rt];
    rt=tot-1;
    A[rt].sum++;
    if(l==r)return;
    if(x<=(l+r)/2)build(x,A[rt].L,l,(l+r)/2);
    else build(x,A[rt].R,(l+r)/2+1,r);
}
int ask(int l,int r,int x,int y,int k)
{
    if(l==r)return A[y].sum-A[x].sum;
    if(k>(l+r)/2)return ask((l+r)/2+1,r,A[x].R,A[y].R,k);
    return A[A[y].R].sum-A[A[x].R].sum+ask(l,(l+r)/2,A[x].L,A[y].L,k);
}
int getid(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;;}
int main()
{
    int n,q;
    while(scanf("%d%d",&n,&q)!=EOF)
    {
        init();
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),v.push_back(a[i]);
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());
        for(int i=1;i<=n;i++)
        {
            root[i]=root[i-1];
            build(getid(a[i]),root[i],1,n);
        }
        while(q--)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            int l=0,r=n,ans=0;
            while(r>=l)
            {
                int m=(l+r)/2;
                if(ask(1,n,root[x-1],root[y],getid(m))>=m)
                {
                    ans=m;
                    l=m+1;
                }
                else r=m-1;
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}


你可能感兴趣的:(数据结构-划分树//主席树)