Codeforces Round #136 (Div. 1) B. Little Elephant and Array
The Little Elephant loves playing with arrays. He has array a, consisting of n positive integers, indexed from 1 to n. Let's denote the number with index i as ai.
Additionally the Little Elephant has m queries to the array, each query is characterised by a pair of integers lj and rj (1 ≤ lj ≤ rj ≤ n). For each query lj, rj the Little Elephant has to count, how many numbers x exist, such that number x occurs exactly x times among numbers alj, alj + 1, ..., arj.
Help the Little Elephant to count the answers to all queries.
The first line contains two space-separated integers n and m (1 ≤ n, m ≤ 105) — the size of array a and the number of queries to it. The next line contains n space-separated positive integers a1, a2, ..., an (1 ≤ ai ≤ 109). Next m lines contain descriptions of queries, one per line. The j-th of these lines contains the description of the j-th query as two space-separated integers lj and rj (1 ≤ lj ≤ rj ≤ n).
In m lines print m integers — the answers to the queries. The j-th line should contain the answer to the j-th query.
7 2
3 1 2 2 3 3 7
1 7
3 4
3
1
思路:求区间l,r内,一个数的出现次数等于他本身的数的个数。莫队板子。
错因:函数hash冲突。
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 100001 using namespace std; int n,m,S,ans; int sum[MAXN],num[MAXN],has[MAXN]; struct nond{ int l,r,id,pos,ans; }edge[MAXN]; int cmp1(nond a,nond b){ return a.id<b.id; } int cmp(nond a,nond b){ if(a.pos==b.pos) return a.r<b.r; else return a.pos<b.pos; } void up(int x,int k){ if(sum[num[x]]!=has[num[x]]&&sum[num[x]]+k==has[num[x]]) ans++; else if(sum[num[x]]==has[num[x]]&&sum[num[x]]+k!=has[num[x]]) ans--; sum[num[x]]+=k; } void mode(){ int l=1,r=0; for(int i=1;i<=m;i++){ while(l<edge[i].l) up(l++,-1); while(l>edge[i].l) up(--l,1); while(r<edge[i].r) up(++r,1); while(r>edge[i].r) up(r--,-1); edge[i].ans=ans; } } int main(){ scanf("%d%d",&n,&m); S=sqrt(n); for(int i=1;i<=n;i++){ scanf("%d",&num[i]); has[i]=num[i]; } sort(has+1,has+1+n); int cnt=unique(has+1,has+1+n)-(has+1); for(int i=1;i<=n;i++) num[i]=lower_bound(has+1,has+cnt+1,num[i])-has; for(int i=1;i<=m;i++){ scanf("%d%d",&edge[i].l,&edge[i].r); edge[i].id=i; edge[i].pos=(edge[i].l-1)/S+1; } sort(edge+1,edge+1+m,cmp); mode(); sort(edge+1,edge+1+m,cmp1); for(int i=1;i<=m;i++) cout<<edge[i].ans<<endl; }