Little Elephant and Array CodeForces - 220B (莫队)

The Little Elephant loves playing with arrays. He has array a, consisting of npositive 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, rjthe Little Elephant has to count, how many numbers x exist, such that number xoccurs 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 a1a2..., 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
7 2
3 1 2 2 3 3 7
1 7
3 4
Output
3
1

题意:
问区间内含有出现次数等于其值的数字个数
思路:
莫队。
没有什么值得解释的,只不过预处理离散化将时间由3790 ms优化到186 ms,必须写一个博客纪念一下。
  1 #include<iostream>
  2 #include<algorithm>
  3 #include<vector>
  4 #include<stack>
  5 #include<queue>
  6 #include<map>
  7 #include<set>
  8 #include<cstdio>
  9 #include<cstring>
 10 #include<cmath>
 11 #include<ctime>
 12 #define fuck(x) cout<<#x<<" = "<<x<<endl;
 13 #define debug(a,i) cout<<#a<<"["<<i<<"] = "<<a[i]<<endl;
 14 #define ls (t<<1)
 15 #define rs ((t<<1)+1)
 16 using namespace std;
 17 typedef long long ll;
 18 typedef unsigned long long ull;
 19 const int maxn = 100086;
 20 const int maxm = 100086;
 21 const int inf = 2.1e9;
 22 const ll Inf = 999999999999999999;
 23 const int mod = 1000000007;
 24 const double eps = 1e-6;
 25 const double pi = acos(-1);
 26 int num[maxn];
 27 struct node{
 28     int l,r;
 29     int id;
 30 }a[maxm];
 31 int anss[maxm];
 32 int block;
 33 
 34 bool cmp(node a,node b){
 35     return (a.l/block!=b.l/block)?a.l<b.l:a.r<b.r;
 36 }
 37 int vis[100088];
 38 int rem[maxn],cnt;
 39 int pos[maxn];
 40 int get_id(int x){
 41     return lower_bound(rem+1,rem+1+cnt,x)-rem;
 42 }
 43 
 44 int main()
 45 {
 46     int n;
 47     scanf("%d",&n);
 48     int m;
 49     scanf("%d",&m);
 50     for(int i=1;i<=n;i++){
 51         scanf("%d",&num[i]);
 52         rem[i]=num[i];
 53     }
 54     block=sqrt(n);
 55     for(int i=1;i<=m;i++){
 56         scanf("%d%d",&a[i].l,&a[i].r);
 57         a[i].id=i;
 58     }
 59 
 60     sort(a+1,a+1+m,cmp);
 61     sort(rem+1,rem+1+n);
 62 
 63     cnt=unique(rem+1,rem+1+n)-rem-1;
 64     for(int i=1;i<=n;i++){
 65         pos[i]=get_id(num[i]);
 66     }
 67     int L=1,R=0;
 68     int ans=0;
 69     num[0]=-1;
 70     for(int i=1;i<=m;i++){
 71         while(R<a[i].r){
 72             R++;
 73             if(vis[pos[R]]==num[R]){ans--;}
 74             vis[pos[R]]++;
 75             if(vis[pos[R]]==num[R]){ans++;}
 76         }
 77         while(L<a[i].l){
 78             if(vis[pos[L]]==num[L]){ans--;}
 79             vis[pos[L]]--;
 80             if(vis[pos[L]]==num[L]){ans++;}
 81             L++;
 82 
 83         }
 84         while(R>a[i].r){
 85             if(vis[pos[R]]==num[R]){ans--;}
 86             vis[pos[R]]--;
 87             if(vis[pos[R]]==num[R]){ans++;}
 88             R--;
 89         }
 90         while(L>a[i].l){
 91             L--;
 92             if(vis[pos[L]]==num[L]){ans--;}
 93             vis[pos[L]]++;
 94             if(vis[pos[L]]==num[L]){ans++;}
 95         }
 96         anss[a[i].id]=ans;
 97     }
 98     for(int i=1;i<=m;i++){
 99         printf("%d\n",anss[i]);
100     }
101     return 0;
102 }
View Code
posted @ 2019-05-13 19:24  断腿三郎  阅读(244)  评论(0编辑  收藏  举报