Codeforces 220B
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间有几个数的出现次数等于数值本身。
由于题目满足由区间(l,r)-> (l,r+1)、(l,r-1)、(l-1,r)、(l+1,r)的快速转移,所以可以用莫队算法。刚接触不是太懂,等以后更加了解再更。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=100010; 5 const int maxm=100010; 6 int n,m,unit; 7 struct Query{ 8 int l,r,id; 9 }node[maxm]; 10 11 int a[maxn],b[maxn],c[maxn],num[maxn],ans[maxm]; 12 13 bool cmp(Query a,Query b) { 14 if(a.l/unit!=b.l/unit) return a.l/unit<b.l/unit; 15 else return a.r<b.r; 16 } 17 18 int main() { 19 scanf("%d%d",&n,&m); 20 unit=(int)sqrt(n*1.0); 21 for(int i=1;i<=n;i++) { 22 scanf("%d",&a[i]); 23 b[i]=a[i]; 24 } 25 sort(b+1,b+1+n); 26 for(int i=1;i<=n;i++) { 27 c[i]=lower_bound(b+1,b+1+n,a[i])-b; 28 } 29 for(int i=1;i<=m;i++) { 30 node[i].id=i; 31 scanf("%d%d",&node[i].l,&node[i].r); 32 } 33 sort(node+1,node+m+1,cmp); 34 int l=1,r=0,temp=0; 35 for(int i=1;i<=m;i++) { 36 while(r<node[i].r) { //右扩 37 r++; 38 if(num[c[r]]+1==a[r]) temp++; 39 else if(num[c[r]]==a[r]) temp--; 40 num[c[r]]++; 41 } 42 while(r>node[i].r) { //右缩 43 if(num[c[r]]==a[r]) temp--; 44 else if(num[c[r]]-1==a[r]) temp++; 45 num[c[r]]--; 46 r--; 47 } 48 while(l>node[i].l) { //左扩 49 l--; 50 if(num[c[l]]+1==a[l]) temp++; 51 else if(num[c[l]]==a[l]) temp--; 52 num[c[l]]++; 53 } 54 while(l<node[i].l) { //左缩 55 if(num[c[l]]==a[l]) temp--; 56 else if(num[c[l]]-1==a[l]) temp++; 57 num[c[l]]--; 58 l++; 59 } 60 ans[node[i].id]=temp; 61 } 62 for(int i=1;i<=m;i++) printf("%d\n",ans[i]); 63 }