Problem Description
The
h
h
h-index of an author is the largest
h
h
h where he has at least
h
h
h papers with citations not less than
h
h
h.
Bobo has published
n
n
n papers with citations
a
1
a_1
a1,
a
2
a_2
a2,…,
a
n
a_n
an respectively.
One day, he raises
q
q
q questions. The i-th question is described by two integers
l
i
l_i
li and
r
i
r_i
ri, asking the
h
h
h-index of Bobo if has only published papers with citations
a
l
i
a_{l_i}
ali,
a
l
i
+
1
a_{l_{i+1}}
ali+1,…,
a
r
i
a_{r_i}
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
n
n and
q
q
q.
The second line contains
n
n
n integers
a
1
a_1
a1,
a
2
a_2
a2,…,
a
n
a_n
an.
The
i
i
i-th of last
q
q
q lines contains two integers
l
i
l_i
li and
r
i
r_i
ri.
Output
For each question, print an integer which denotes the answer.
Constraint
- 1 ≤ n , q ≤ 1 0 5 1≤n,q≤10^5 1≤n,q≤105
- 1 ≤ a i ≤ n 1≤a_i≤n 1≤ai≤n
- 1 ≤ l i ≤ r i ≤ n 1≤l_i≤r_i≤n 1≤li≤ri≤n
- The sum of n n n does not exceed 250,000.
- The sum of q q 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
n
n的数组
a
a
a,有
m
m
m次询问,每次询问输入一个区间
[
l
,
r
]
[l,r]
[l,r],输出一个值
h
h
h满足:
- 区间 [ l , r ] [l,r] [l,r]内存在 h h h或更多个 a i a_i ai满足 a i a_i ai>= h h h
- 不存在更大的满足条件的 h h h
思路
其实是静态区间第
k
k
k小(大)问题,主席树模板。
当然区间可能过大以至于不能枚举,所以要二分答案。
AC代码
#include<stdio.h>
#include<map>
#include<queue>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#define MOD 10000000007
#define N 100005
typedef long long LL;
using namespace std;
typedef struct node{
int lson,rson,va;//va:权值 主席树
}node;
int tot,n,m,te,len,s,t,k;
int a[N],T[N];
node tree[N<<5];
int R[N];
void init()
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);T[i]=a[i];
}
sort(T+1,T+n+1);
len=unique(T+1,T+n+1)-T-1;
}
void build(int &root,int l,int r)
{
root=++tot;
if(l==r)return;
int mid=(l+r)/2;
build(tree[root].lson,l,mid);
build(tree[root].rson,mid+1,r);
return;
}
int find(int target)
{
return lower_bound(T+1,T+len+1,target)-T;
}
void insert(int pre,int &root,int l,int r,int pos)
{
tree[++tot]=tree[pre];root=tot;
if(l==r)
{
tree[root].va++;return;
}
int mid=(l+r)/2;
if(pos>mid) insert(tree[root].rson,tree[root].rson,mid+1,r,pos);else insert(tree[root].lson,tree[root].lson,l,mid,pos);
tree[root].va++;
return;
}
int query(int from,int to,int k,int l,int r)
{
if(l==r)return l;
int sum=tree[tree[to].lson].va-tree[tree[from].lson].va;
int mid=(l+r)/2;
if(k>sum)
return query(tree[from].rson,tree[to].rson,k-sum,mid+1,r);
else
return query(tree[from].lson,tree[to].lson,k,l,mid);
}
int binarysearch(int l,int r)
{
int l_=l,r_=r,mid,ans;
while(l_<=r_)
{
mid=(l_+r_)/2;
ans=T[query(R[l-1],R[r],(r-l+1+1)-(mid-l+1),1,len)];
if(ans>=(mid-l+1))l_=mid+1;else r_=mid-1;
}
return l_-l;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
tot=0;
build(R[0],1,n);
for(int i=1;i<=n;i++) insert(R[i-1],R[i],1,len,find(a[i]));//insert函数实际上是将原始数据离散化后的值插入权值线段树,故此时的l=1,r=离散化后剩余的元素数
for(int i=1;i<=m;i++)
{
scanf("%d%d",&s,&t);
printf("%d\n",binarysearch(s,t));
}
}
return 0;
}