Codeforces Round #136 (Div. 1) 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
7 2
3 1 2 2 3 3 7
1 7
3 4
output
3
1

 思路:求区间l,r内,一个数的出现次数等于他本身的数的个数。莫队板子。

错因:函数hash冲突。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100001 
using namespace std;
int n,m,S,ans;
int sum[MAXN],num[MAXN],has[MAXN];
struct nond{
    int l,r,id,pos,ans;
}edge[MAXN];
int cmp1(nond a,nond b){
    return a.id<b.id;
}
int cmp(nond a,nond b){
    if(a.pos==b.pos)    return a.r<b.r;
    else return a.pos<b.pos;
}
void up(int x,int k){
    if(sum[num[x]]!=has[num[x]]&&sum[num[x]]+k==has[num[x]])    ans++;
    else if(sum[num[x]]==has[num[x]]&&sum[num[x]]+k!=has[num[x]])    ans--;
    sum[num[x]]+=k;
}
void mode(){
    int l=1,r=0;
    for(int i=1;i<=m;i++){
        while(l<edge[i].l)    up(l++,-1);
        while(l>edge[i].l)    up(--l,1);
        while(r<edge[i].r)    up(++r,1);
        while(r>edge[i].r)    up(r--,-1);
        edge[i].ans=ans;
    }
}
int main(){
    scanf("%d%d",&n,&m);
    S=sqrt(n);
    for(int i=1;i<=n;i++){
        scanf("%d",&num[i]);
        has[i]=num[i];
    }
    sort(has+1,has+1+n);
    int cnt=unique(has+1,has+1+n)-(has+1);
    for(int i=1;i<=n;i++)
        num[i]=lower_bound(has+1,has+cnt+1,num[i])-has;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&edge[i].l,&edge[i].r);
        edge[i].id=i;
        edge[i].pos=(edge[i].l-1)/S+1;
    }
    sort(edge+1,edge+1+m,cmp);
    mode();
    sort(edge+1,edge+1+m,cmp1);
    for(int i=1;i<=m;i++)
        cout<<edge[i].ans<<endl;
} 

 

posted @ 2017-09-08 20:23  一蓑烟雨任生平  阅读(216)  评论(0编辑  收藏  举报