题目链接<http://codeforces.com/problemset/problem/220/B>
题意:
有n个数,m个区间。问区间内有多少个x,x满足x的个数等于x的值的个数(如果x是3,区间内要存在3个3)。
题解:
莫队就是离线问题+区间的移动。复杂度是O((N+M)*√N)
题目的数据范围较大,不能用map,map会多出logn的复杂度,在本题会TLE。所以需要对每个值进行离散化的操作。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <stack>
#include <string>
using namespace std;
typedef long long ll;
using namespace std;
const int N=1e5+7;
int unit,n,m;
map<int,int>mp;
struct Node{
int l,r,id;
bool operator<(const Node a)const{
return l/unit==a.l/unit?r<a.r:l<a.l;
}
}q[N];
int a[N],b[N],num[N],pr[N],ans;
void add(int i){
num[a[i]]++;
if(num[a[i]]==b[a[i]]) ans++;
else if(num[a[i]]==b[a[i]]+1) ans--;
}
void dele(int i){
num[a[i]]--;
if(num[a[i]]==b[a[i]]) ans++;
else if(num[a[i]]==b[a[i]]-1) ans--;
}
int main(){
scanf("%d%d",&n,&m);
unit=(int)sqrt(n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
int cnt=unique(b+1,b+1+n)-(b+1);
for(int i=1;i<=n;i++){
a[i]=lower_bound(b+1,b+1+cnt,a[i])-b;
}
for(int i=1;i<=m;i++){
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q+1,q+1+m);
int le=q[1].l,ri=le-1;
for(int i=1;i<=m;i++){
while(le>q[i].l) add(--le);
while(ri<q[i].r) add(++ri);
while(le<q[i].l) dele(le++);
while(ri>q[i].r) dele(ri--);
pr[q[i].id]=ans;
}
for(int i=1;i<=m;i++)
printf("%d\n",pr[i]);
}