https://vjudge.net/problem/CodeForces-220B
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<vector>
#include<string.h>
#include<queue>
#include<cmath>
#define mem(a, b) memset(a, b, sizeof(a))
#define LL long long
#define N 100001
#define MOD
using namespace std;
int n, m, a[N], bl[N], block, ans, rep[N], cnt, vis[N];
struct node{
int l, r, id, ans;
}q[N];
bool cmp1(node x, node y) {
if(x.l/block==y.l/block) return x.r<y.r;
return x.l<y.l;
}
bool cmp2(node x, node y) {
return x.id<y.id;
}
int get(int x) {
return lower_bound(rep+1, rep+1+cnt, x)-rep;
}
void mo() {//莫队
int l=1, r=0, tl, tr, ans=0;
a[0]=-1;
for(int i=1; i<=m; i++) {
tl=q[i].l, tr=q[i].r;
while(l<tl) {//如果l<rl,那么l要往右移,如果当前的a[l]符合条件,移动后,数量减一,就会不符合,所以答案减一
if(vis[bl[l]]==a[l]) ans--;
vis[bl[l]]--;//如果减去a[l]的个数,符合条件,答案加一
if(vis[bl[l]]==a[l]) ans++;
l++;
}
while(l>tl) {
l--;
if(vis[bl[l]]==a[l]) ans--;
vis[bl[l]]++;
if(vis[bl[l]]==a[l]) ans++;
}
while(r>tr) {
if(vis[bl[r]]==a[r]) ans--;
vis[bl[r]]--;
if(vis[bl[r]]==a[r]) ans++;
r--;
}
while(r<tr) {
r++;
if(vis[bl[r]]==a[r]) ans--;
vis[bl[r]]++;
if(vis[bl[r]]==a[r]) ans++;
}
q[i].ans=ans;
}
}
int main() {
scanf("%d%d",&n, &m);
block=sqrt(n);
for(int i=1; i<=n; i++){
scanf("%d",&a[i]);
rep[i]=a[i];//离散化
}
for(int i=1; i<=m; i++){
scanf("%d%d", &q[i].l, &q[i].r);
q[i].id=i;
}
sort(rep+1, rep+1+n);//先排序
cnt=unique(rep+1, rep+1+n)-rep-1;//去重
for(int i=1; i<=n; i++){
bl[i]=get(a[i]);//离散化
}
sort(q+1, q+1+m, cmp1);
mo();
sort(q+1, q+1+m, cmp2);
for(int i=1; i<=m; i++){
printf("%d\n", q[i].ans);
}
return 0;
}