Codeforces 220B

B. Little Elephant and Array
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

Input

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).

Output

In m lines print m integers — the answers to the queries. The j-th line should contain the answer to the j-th query.

Examples
input
Copy
7 2
3 1 2 2 3 3 7
1 7
3 4
output
Copy
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 }

 

 
posted @ 2019-05-14 21:18  Frontierone  阅读(174)  评论(0编辑  收藏  举报