有 n 个数,给定 m 个区间,问这个区间内有几个数 x 满足 x=区间内 x 的个数
由于 a[i] 的数据范围太大,可以考虑离散,但是区间内的个数也应该满足 [1,n] ,所以只需要将 a[i]>n 的那部分忽略加以莫队即可
const int N=1e5+5;
int n,m,t;
int i,j,k;
int a[N];
int block,belong[N];
int ans[N],now=0;
int cnt[N];
struct node
{
int l,r;
int id;
}q[N];
bool cmp(node a,node b)
{
return belong[a.l]^belong[b.l] ? belong[a.l]>belong[b.l] : ( (belong[a.l]&1) ? a.r<b.r : a.r>b.r);
}
void add(int x)
{
if(cnt[a[x]]==a[x]) now--;
cnt[a[x]]++;
if(cnt[a[x]]==a[x]) now++;
}
void del(int x)
{
if(cnt[a[x]]==a[x]) now--;
cnt[a[x]]--;
if(cnt[a[x]]==a[x]) now++;
}
int main()
{
//IOS;
while(sdd(n,m)==2){
for(i=1;i<=n;i++){
sd(a[i]);
if(a[i]>n) a[i]=-1;
}
for(i=1;i<=m;i++){
sdd(q[i].l,q[i].r);
q[i].id=i;
}
block=sqrt(n);
for(i=1;i<=n;i++) belong[i]=i/block;
sort(q+1,q+1+m,cmp);
int l=1,r=0;
for(i=1;i<=m;i++){
while(l<q[i].l) del(l++);
while(l>q[i].l) add(--l);
while(r<q[i].r) add(++r);
while(r>q[i].r) del(r--);
ans[q[i].id]=now;
}
for(i=1;i<=m;i++) pd(ans[i]);
}
//PAUSE;
}