Just h-index
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 548 Accepted Submission(s): 256
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≤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
题意:给你n个数,m次查询, 每次求一个最大的m满足:在这个区间中有至少m个数大于等于m
因为每个数都≤n,所以不用离散化直接按权值建主席树
模板题,就是求区间第k大稍微变一下下(模板改一行)
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n, m, tot, t[100005], a[100005];
typedef struct
{
int l, r;
int size;
}Ctree;
Ctree s[3233333];
int Build(int l, int r);
int Update(int root, int x);
int Query(int lx, int rx);
int main(void)
{
int i, l, r;
while(scanf("%d%d", &n, &m)!=EOF)
{
tot = 0;
for(i=1;i<=n;i++)
scanf("%d", &a[i]);
t[0] = Build(1, n);
for(i=1;i<=n;i++)
t[i] = Update(t[i-1], a[i]);
while(m--)
{
scanf("%d%d", &l, &r);
printf("%d\n", Query(t[l-1], t[r]));
}
}
return 0;
}
int Build(int l, int r)
{
int m, root;
root = ++tot;
m = (l+r)/2;
s[root].size = 0;
if(l==r)
return root;
s[root].l = Build(l, m);
s[root].r = Build(m+1, r);
return root;
}
int Update(int root, int x)
{
int now, tmp, l, r, m;
tmp = now = ++tot;
l = 1, r = n;
while(l<r)
{
s[now].size = s[root].size+1;
m = (l+r)/2;
if(x<=m)
{
s[now].l = ++tot;
s[now].r = s[root].r;
root = s[root].l;
now = tot;
r = m;
}
else
{
s[now].l = s[root].l;
s[now].r = ++tot;
root = s[root].r;
now = tot;
l = m+1;
}
}
s[now].size = s[root].size+1;
return tmp;
}
int Query(int lx, int rx)
{
int l, r, m, now;
l = 1, r = n;
now = 0;
while(l<r)
{
m = (l+r)/2;
if(s[s[rx].r].size-s[s[lx].r].size+now<=m)
{
r = m;
now += s[s[rx].r].size-s[s[lx].r].size;
lx = s[lx].l;
rx = s[rx].l;
}
else
{
l = m+1;
lx = s[lx].r;
rx = s[rx].r;
}
}
return r;
}