C - Just hhh-index
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
-
1≤n,q≤105
-
1≤ai≤n
-
1≤li≤ri≤n
-
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为一个数组中最大的h使数组中大于等于h的数字个数大于等于h
给一个数组,每次询问子数组中h值
设数组长度为len,即数组中第h大的数字大于等于h
h范围在1到len之间,二分加第k大即可求出答案#include<stdio.h>
#include
#include
#define maxl 100005
using namespace std;
int n,q;
int nn,tot;
int rt[maxl],a[maxl],b[maxl];
struct node
{
int ls,rs,sum;
}tree[maxl*20];
void insert(int num,int &x,int l,int r)
{
tree[++tot]=tree[x];
x=tot;
++tree[x].sum;
if(l==r) return;
int mid=(l+r)>>1;
if(num<=mid)
insert(num,tree[x].ls,l,mid);
else
insert(num,tree[x].rs,mid+1,r);
}void prework()
{
tree[0].ls=tree[0].rs=tree[0].sum=0;
rt[0]=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
nn=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++)
a[i]=lower_bound(b+1,b+nn+1,a[i])-b;
tot=0;
for(int i=1;i<=n;i++)
{
rt[i]=rt[i-1];
insert(a[i],rt[i],1,nn);
}
}int query(int i,int j,int k,int l,int r)
{
if(l==r)
return l;
int tp=tree[tree[j].ls].sum-tree[tree[i].ls].sum;
int mid=(l+r)>>1;
if(k<=tp)
return query(tree[i].ls,tree[j].ls,k,l,mid);
else
return query(tree[i].rs,tree[j].rs,k-tp,mid+1,r);
}
int main()
{
while(~scanf("%d%d",&n,&q))
{
tot=0;
prework();
while(q–)
{
int L,R;
scanf("%d%d",&L,&R);
int l=1,r=R-L+1;
while(r>l+1)
{
int mid=(l+r)/2;
if(b[query(rt[L-1],rt[R],R-L-mid+2,1,nn)]>=mid)
l=mid;
else
r=mid;
}
if(b[query(rt[L-1],rt[R],R-L-r+2,1,nn)]>=r)
printf("%d\n",r);
else
printf("%d\n",l);
}
}
}