离散化+莫队

https://codeforces.com/problemset/problem/220/B

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.

input
Copy
7 2
3 1 2 2 3 3 7
1 7
3 4
output
Copy
3
1

这个题就是说问你lj和rj区间中有多少个数字x存在,这样数字x在数字alj, alj + 1,…,arj中正好出现x次。
比如说样例中1-7中,1出现了一次,2出现了两次,3出现了三次
3-4中只有2出现了两次

这个题的a[i]的数据范围是1e9,数组开不开,所以要离散化

#include<iostream>
#include<algorithm>
#include<map>
#include<math.h> 
using namespace std;
const int maxn=1e6+100;
int a[maxn],b[maxn],c[maxn];
int belong[maxn],res[maxn];
struct node{
    int l,r,id;
}q[maxn]; 
int ans=0;
int mp[maxn];
int cnt=0;
bool cmp(node x,node y){
    if(belong[x.l]!=belong[y.l]){
        return x.l<y.l;
    }
    else{
        if(belong[x.l]&1){
            return x.r<y.r;
        }
        else{
            return x.r>y.r;
        }
    }
}
void add(int pos){
    if(mp[a[pos]]==c[pos]){
        ans--;
    }
    mp[a[pos]]++;
    if(mp[a[pos]]==c[pos]){
        ans++;
    }
}
void remove(int pos){
    if(mp[a[pos]]==c[pos]){
        ans--;
    }
    mp[a[pos]]--;
    if(mp[a[pos]]==c[pos]){
        ans++;
    }
} 
int main(){
    int n,m;
    cin>>n>>m;
    int block=(int)sqrt(n);
    for(int i=1;i<=n;i++){
        cin>>a[i];
        b[i]=c[i]=a[i];
        belong[i]=(i-1)/block+1;
    }
    sort(b+1,b+n+1);
    for(int i=1;i<=n;i++){
        a[i]=lower_bound(b+1,b+n+1,a[i])-b;
    }
    for(int i=1;i<=m;i++){
        cin>>q[i].l>>q[i].r;
        q[i].id=i;
    } 
    sort(q+1,q+m+1,cmp);
    for(int l=1,r=0,i=1;i<=m;i++){
        int ql=q[i].l,qr=q[i].r;
        while(l<ql){
            remove(l++);
        }    
        while(l>ql){
            add(--l);
        } 
        while(r>qr){
            remove(r--);
        } 
        while(r<qr){
            add(++r);
        }
        res[q[i].id]=ans;
    }
    for(int i=1;i<=m;i++){
        cout<<res[i]<<endl;
    }
}




原文地址:https://www.cnblogs.com/lipu123/p/14471063.html