SPOJ DOUERY query 【莫队】

Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, ..., aj.

Input

  • Line 1: n (1 ≤ n ≤ 30000).
  • Line 2: n numbers a1, a2, ..., an (1 ≤ ai ≤ 106).
  • Line 3: q (1 ≤ q ≤ 200000), the number of d-queries.
  • In the next q lines, each line contains 2 numbers i, j representing a d-query (1 ≤ i ≤ j ≤ n).

Output

  • For each d-query (i, j), print the number of distinct elements in the subsequence ai, ai+1, ..., aj in a single line.

Example

Input
5
1 1 2 1 3
3
1 5
2 4
3 5

Output
3
2
3 
#include<bits/stdc++.h>
using namespace std;
const int MAX = 2e6 + 7;
int n, sz;
struct node{
    int l, r, id;
    bool operator < (const node &a) const{
        if(l / sz == a.l / sz)
            return r < a.r;
        return l / sz < a.l / sz;
    }
} mo[MAX];
int ans = 0;
int res[MAX];
int cnt[MAX];
int a[MAX];
void add(int pos){
    cnt[a[pos]]++;
    if(cnt[a[pos]] == 1)
        ans++;
}
void del(int pos){
    cnt[a[pos]]--;
    if(cnt[a[pos]] == 0)
        ans--;
}
int main(){
    int m;
    scanf("%d", &n);
    sz = sqrt(n);
    for(int i = 0; i < n; i++)
        scanf("%d", &a[i]);
    scanf("%d", &m);
    for(int i = 0; i < m; i++){
        scanf("%d%d", &mo[i].l, &mo[i].r);
        mo[i].l--;
        mo[i].r--;
        mo[i].id = i;
    }
    sort(mo, mo + m);
    int p = 0, q = 0;
    for(int i = 0; i < m; i++){
        int L = mo[i].l;
        int R = mo[i].r;
        while(p < L){
            del(p);
            p++;
        }
        while(p > L){
            add(p - 1);
            p--;
        }
        while(q <= R){
            add(q);
            q++;
        }
        while(q > R + 1){
            del(q - 1);
            q--;
        }
        res[mo[i].id] = ans;
    }
    for(int i = 0; i < m; i++)
        printf("%d\n", res[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/head_hard/article/details/81118359