http://acm.hdu.edu.cn/showproblem.php?pid=6278
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 1250 Accepted Submission(s): 566
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
* 1≤n,q≤10^5
* 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
Source
CCPC2018-湖南全国邀请赛-重现赛(感谢湘潭大学)
题解
主席树求区间大于等于k的个数+二分查找
C++代码
#include
#include
using namespace std;
const int N=100100;
int a[N],b[N],rt[20*N],ls[20*N],rs[20*N],sum[20*N];
int id;
void build(int &o,int l,int r)
{
o=++id;
sum[o]=0;
if(l==r) return;
int m=(l+r)>>1;
build(ls[o],l,m);
build(rs[o],m+1,r);
}
void update(int &o,int l,int r,int last,int p)
{
o=++id;
ls[o]=ls[last];
rs[o]=rs[last];
sum[o]=sum[last]+1;
if(l==r) return;
int m=(l+r)>>1;
if(p<=m)
update(ls[o],l,m,ls[last],p);
else
update(rs[o],m+1,r,rs[last],p);
}
//查询区间[L+1,R]内大于等于k的个数
int query(int L,int R,int l,int r,int k)
{
if(b[l]>=k) return sum[R]-sum[L];
if(l==r) return 0;
int m=(l+r)>>1;
int sum=0;
if(b[m]>=k)
sum+=query(ls[L],ls[R],l,m,k);
sum+=query(rs[L],rs[R],m+1,r,k);
return sum;
}
int main()
{
int n,q;
while(~scanf("%d%d",&n,&q))
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+n+1);
int size=unique(b+1,b+n+1)-(b+1);
id=0;
build(rt[0],1,size);
for(int i=1;i<=n;i++)
{
a[i]=lower_bound(b+1,b+1+size,a[i])-b;
update(rt[i],1,size,rt[i-1],a[i]);
}
while(q--)
{
int L,R;
scanf("%d%d",&L,&R);
int l=0,r=R-L+1;
while(l<=r)
{
int m=(l+r)>>1;
if(query(rt[L-1],rt[R],1,size,m)
你可能感兴趣的:(数据结构)