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
31
查询某个区间内一个数a满足a出现的次数==a,求这样的数的个数。
无修改,所以莫队!
/* *===================== *File Name:a.cpp *Author: qqspeed *Date: 2014年 07月 06日 星期日 13:42:33 CST *===================== */ #include <stdio.h> #include <string.h> #include <iostream> #include <string> #include <queue> #include <stack> #include <map> #include <math.h> #include <vector> #include <stdlib.h> #include <algorithm> using namespace std; typedef long long ll; #define rep(i,s,t) for(int i=s;i<t;i++) #define red(i,s,t) for(int i=s-1;i>=t;i--) #define ree(i,now) for(int i=head[now];i!=-1;i=edge[i].next) #define clr(a,v) memset(a,v,sizeof a) #define L t<<1 #define R t<<1|1 #define MID int mid=(l+r)>>1 #define max(a,b) (a<b?b:a) #define min(a,b) (a<b?a:b) #define SQR(a) ((a)*(a)) inline int input(){ int ret=0;bool isN=0;char c=getchar(); while(c<'0' || c>'9'){ if(c=='-') isN=1; c=getchar(); } while(c>='0' && c<='9'){ ret=ret*10+c-'0'; c=getchar(); } return isN?-ret:ret; } inline void output(int x){ if(x<0){ putchar('-');x=-x; } int len=0,data[11]; while(x){ data[len++]=x%10;x/=10; } if(!len) data[len++]=0; while(len--) putchar(data[len]+48); putchar('\n'); } const int MAXN=100005; int n,m; int a[MAXN],x[MAXN],cnt; int S,pos[MAXN],ans[MAXN]; int num[MAXN]; int s; struct Q{ int l,r; int id; }q[MAXN]; bool cmp(Q i,Q j){ return pos[i.l]<pos[j.l] || (pos[i.l]==pos[j.l] && i.r<j.r); } inline void add(int w,int v){ w=a[w]; if(num[w]==x[w]){ s--; } num[w]+=v; if(num[w]==x[w]){ s++; } } int main(){ n=input();m=input(); S=(int)(sqrt(n+0.5));clr(num,0); rep(i,0,n+1){ pos[i]=(i-1)/S; } cnt=1; rep(i,1,n+1){ a[i]=input(); x[cnt++]=a[i]; } sort(x+1,x+cnt); cnt=unique(x+1,x+cnt)-(x+1); rep(i,1,n+1){ a[i]=lower_bound(x+1,x+cnt+1,a[i])-x; } rep(i,0,m){ q[i].l=input(),q[i].r=input(); q[i].id=i; } sort(q,q+m,cmp); int l=1,r=0;s=0; rep(i,0,m){ if(r<q[i].r){ for(r=r+1;r<=q[i].r;r++) add(r,1); r--; } if(r>q[i].r){ for(;r>q[i].r;r--) add(r,-1); } if(l>q[i].l){ for(l=l-1;l>=q[i].l;l--) add(l,1); l++; } if(l<q[i].l){ for(;l<q[i].l;l++) add(l,-1); } ans[q[i].id]=s; } rep(i,0,m) output(ans[i]); }