Just h-index
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 407 Accepted Submission(s): 184
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.
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.
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.
## 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 31 5 3 2 11 32 41 55 11 2 3 4 51 5
Sample Output
2223
题意:
给你一个长度为n的序列,有m个询问
每一个询问[l,r]询问序列中在该区间内的数最大的k下标,(k下标是满足该区间至少有k个数的值是大于k的)
解析:
k下标的意思就是满足区间内第k大数的值大于k这个条件的k,然后找这些满足条件的k中的最大值。
思路就是对每一个区间长度二分,[l,r]的话,左端点就是1,右端点就是r-l+1。
然后通过主席树找区间内的第mid大的数,这样最后二分的结果就是最大的k了
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1e5+5;
//const int MAXM = (1e5+5)*15;
typedef struct node
{
int x;
int id;
}node;
int a[MAXN];
int ran[MAXN];
int rt[MAXN*20],ls[MAXN*20],rs[MAXN*20],tot,sz;
int sum[MAXN*20];
bool cmp(node a,node b)
{
return a.x<b.x;
}
void build(int& root,int l,int r)
{
root=++tot;
sum[root]=0;
if(l==r) return;
int mid=(l+r)>>1;
build(ls[root],l,mid);
build(rs[root],mid+1,r);
}
void update(int& root,int l,int r,int last,int x)
{
root=++tot;
ls[root]=ls[last];
rs[root]=rs[last];
sum[root]=sum[last]+1;
if(l==r) return ;
int mid=(l+r)>>1;
if(mid>=x) update(ls[root],l,mid,ls[last],x);
else update(rs[root],mid+1,r,rs[last],x);
}
int query(int ss,int tt,int l,int r,int k)
{
if(l==r) return l;
int cnt=sum[rs[tt]]-sum[rs[ss]];
int mid=(l+r)>>1;
if(k>cnt) return query(ls[ss],ls[tt],l,mid,k-cnt);
else return query(rs[ss],rs[tt],mid+1,r,k);
}
int solve(int s,int e)
{
int r=e-s+1;
int l=1;
int ans=1;
while(l<r)
{
int mid=(l+r)/2;
if(ran[query(rt[s-1],rt[e],1,sz,mid)]>=mid) l=mid+1,ans=mid;
else r=mid;
}
int mid=(l+r)>>1;
if(ran[query(rt[s-1],rt[e],1,sz,mid)]>=mid) l=mid+1,ans=mid;
return ans;
}
int main()
{
int t;
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++) scanf("%d",&a[i]),ran[i]=a[i];
tot=0;
sort(ran+1,ran+1+n);
sz=unique(ran+1,ran+1+n)-(ran+1);
build(rt[0],1,sz);
for(int i=1;i<=n;i++) a[i]=lower_bound(ran+1,ran+1+sz,a[i])-ran;
for(int i=1;i<=n;i++) update(rt[i],1,sz,rt[i-1],a[i]);
for(int i=0;i<m;i++)
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",solve(l,r));
}
}
return 0;
}