对每次询问 找出最大的h 使[l,r]区间内有至少h个数大于等于h 明显有单调性 二分h值即可
#include <bits/stdc++.h>
using namespace std;
struct node
{
int l;
int r;
int val;
};
node tree[2000010];
int ary[100010],tmp[100010],root[100010];
int n,q,len,num;
int build(int l,int r)
{
int cur,m;
cur=num++;
tree[cur].l=0,tree[cur].r=0,tree[cur].val=0;
if(l==r) return cur;
m=(l+r)/2;
tree[cur].l=build(l,m);
tree[cur].r=build(m+1,r);
return cur;
}
int update(int rot,int tar,int l,int r)
{
int cur,m;
cur=num++;
tree[cur]=tree[rot];
tree[cur].val++;
if(l==r) return cur;
m=(l+r)/2;
if(tar<=m) tree[cur].l=update(tree[rot].l,tar,l,m);
else tree[cur].r=update(tree[rot].r,tar,m+1,r);
return cur;
}
int query(int lrot,int rrot,int k,int l,int r)
{
int m;
if(l==r) return l;
m=(l+r)/2;
if(tree[tree[rrot].l].val-tree[tree[lrot].l].val>=k) return query(tree[lrot].l,tree[rrot].l,k,l,m);
else return query(tree[lrot].r,tree[rrot].r,k-(tree[tree[rrot].l].val-tree[tree[lrot].l].val),m+1,r);
}
int main()
{
int i,l,r,pos,pl,pr,m,ans;
while(scanf("%d%d",&n,&q)!=EOF)
{
for(i=1;i<=n;i++)
{
scanf("%d",&ary[i]);
tmp[i]=ary[i];
}
sort(tmp+1,tmp+n+1);
len=unique(tmp+1,tmp+n+1)-tmp-1;
num=0;
root[0]=build(1,len);
for(i=1;i<=n;i++)
{
pos=lower_bound(tmp+1,tmp+len+1,ary[i])-tmp;
root[i]=update(root[i-1],pos,1,len);
}
while(q--)
{
scanf("%d%d",&l,&r);
pl=1,pr=r-l+1;
while(pl<=pr)
{
m=(pl+pr)/2;
int res=query(root[l-1],root[r],r-l+1-m+1,1,len);
if(tmp[res]>=m)
{
ans=m;
pl=m+1;
}
else pr=m-1;
}
printf("%d\n",ans);
}
}
return 0;
}