CodeForces 221D Little Elephant and Array

Little Elephant and Array

Time Limit: 4000ms
Memory Limit: 262144KB
This problem will be judged on CodeForces. Original ID: 221D
64-bit integer IO format: %I64d      Java class name: (Any)

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.

 

Sample Input

Input
7 2
3 1 2 2 3 3 7
1 7
3 4
Output
3
1

Source

 
解题:线段树,甚妙
改段求点
 1 #include <bits/stdc++.h>
 2 #define A first
 3 #define B second
 4 using namespace std;
 5 typedef pair<int,int> pii;
 6 const int maxn = 100010;
 7 int tree[maxn<<2];
 8 inline void pushdown(int v){
 9     if(tree[v]){
10         tree[v<<1] += tree[v];
11         tree[v<<1|1] += tree[v];
12         tree[v] = 0;
13     }
14 }
15 void update(int L,int R,int lt,int rt,int val,int v){
16     if(lt <= L && rt >= R){
17         tree[v] += val;
18         return;
19     }
20     pushdown(v);
21     int mid = (L + R)>>1;
22     if(lt <= mid) update(L,mid,lt,rt,val,v<<1);
23     if(rt > mid) update(mid + 1,R,lt,rt,val,v<<1|1);
24 }
25 int query(int L,int R,int pos,int v){
26     if(L == R) return tree[v];
27     pushdown(v);
28     int mid = (L + R)>>1;
29     if(pos <= mid) return query(L,mid,pos,v<<1);
30     if(pos > mid) return query(mid + 1,R,pos,v<<1|1);
31 }
32 int ans[maxn],a[maxn],cnt[maxn];
33 vector<int>pos[maxn];
34 struct QU{
35     int x,y,id;
36     bool operator<(const QU &rhs)const{
37         return y < rhs.y;
38     }
39 }q[maxn];
40 pii pre[maxn];
41 int main(){
42     int n,m;
43     while(~scanf("%d%d",&n,&m)){
44         memset(tree,0,sizeof tree);
45         memset(cnt,0,sizeof cnt);
46         for(int i = 0; i < n; ++i)
47             scanf("%d",a + i);
48         for(int i = 0; i < m; ++i){
49             scanf("%d%d",&q[i].x,&q[i].y);
50             q[i].id = i;
51         }
52         for(int i = 0; i < maxn; ++i) pos[i].clear();
53         sort(q,q + m);
54         for(int i = 0, j = 0; i < n; ++i){
55             if(a[i] <= n){
56                 pos[a[i]].push_back(i + 1);
57                 cnt[a[i]]++;
58                 if(cnt[a[i]] == a[i]){
59                     pre[a[i]] = pii(1,pos[a[i]][0]);
60                     update(1,n,pre[a[i]].A,pre[a[i]].B,1,1);
61                 }else if(cnt[a[i]] > a[i]){
62                     update(1,n,pre[a[i]].A,pre[a[i]].B,-1,1);
63                     pre[a[i]] = pii(pre[a[i]].B + 1,pos[a[i]][cnt[a[i]] - a[i]]);
64                     update(1,n,pre[a[i]].A,pre[a[i]].B,1,1);
65                 }
66             }
67             while(j < m && q[j].y == i + 1){
68                 ans[q[j].id] = query(1,n,q[j].x,1);
69                 ++j;
70             }
71         }
72         for(int i = 0; i < m; ++i)
73             printf("%d\n",max(0,ans[i]));
74     }
75     return 0;
76 }
View Code

 改点求段

 1 #include <bits/stdc++.h>
 2 #define A first
 3 #define B second
 4 using namespace std;
 5 typedef pair<int,int> pii;
 6 const int maxn = 100010;
 7 int tree[maxn<<2];
 8 void update(int L,int R,int pos,int val,int v){
 9     if(L == R){
10         tree[v] += val;
11         return;
12     }
13     int mid = (L + R)>>1;
14     if(pos <= mid) update(L,mid,pos,val,v<<1);
15     if(pos > mid) update(mid + 1,R,pos,val,v<<1|1);
16     tree[v] = tree[v<<1] + tree[v<<1|1];
17 }
18 int query(int L,int R,int lt,int rt,int v){
19     if(lt <= L && rt >= R) return tree[v];
20     int mid = (L + R)>>1,ret = 0;
21     if(lt <= mid) ret = query(L,mid,lt,rt,v<<1);
22     if(rt > mid) ret += query(mid + 1,R,lt,rt,v<<1|1);
23     return ret;
24 }
25 int a[maxn],cnt[maxn],ans[maxn];
26 vector<int>pos[maxn];
27 struct QU{
28     int x,y,id;
29     bool operator<(const QU &rhs)const{
30         return y < rhs.y;
31     }
32 }q[maxn];
33 int main(){
34     int n,m;
35     while(~scanf("%d%d",&n,&m)){
36         memset(tree,0,sizeof tree);
37         memset(cnt,0,sizeof cnt);
38         for(int i = 0; i < maxn; ++i) pos[i].clear();
39         for(int i = 0; i < n; ++i)
40             scanf("%d",a + i);
41         for(int i = 0; i < m; ++i){
42             scanf("%d%d",&q[i].x,&q[i].y);
43             q[i].id = i;
44         }
45         sort(q,q + m);
46         for(int i = 0,j = 0; i < n; ++i){
47             if(a[i] <= n){
48                 pos[a[i]].push_back(i + 1);
49                 ++cnt[a[i]];
50                 if(cnt[a[i]] >= a[i]) update(1,n,pos[a[i]][cnt[a[i]] - a[i]],1,1);
51                 if(cnt[a[i]] >= a[i] + 1) update(1,n,pos[a[i]][cnt[a[i]] - a[i] - 1],-2,1);
52                 if(cnt[a[i]] > a[i] + 1) update(1,n,pos[a[i]][cnt[a[i]] - a[i] - 2],1,1);
53             }
54             while(j < m && q[j].y == i + 1){
55                 ans[q[j].id] = query(1,n,q[j].x,q[j].y,1);
56                 ++j;
57             }
58         }
59         for(int i = 0; i < m; ++i)
60             printf("%d\n",ans[i]);
61     }
62     return 0;
63 }
View Code

 

posted @ 2015-10-17 13:45  狂徒归来  阅读(283)  评论(0编辑  收藏  举报