[BZOJ1878][SDOI2009]HH的项链

1878: [SDOI2009]HH的项链

Time Limit: 4 Sec  Memory Limit: 64 MB Submit: 4645  Solved: 2302 [Submit][Status][Discuss]

Description

HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一
段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此他的项链变得越来越长。有一天,他突然提出了一
个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只
好求助睿智的你,来解决这个问题。

Input

第一行:一个整数N,表示项链的长度。 
第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。 
第三行:一个整数M,表示HH询问的个数。 
接下来M行:每行两个整数,L和R(1 ≤ L ≤ R ≤ N),表示询问的区间。
N ≤ 50000,M ≤ 200000。

Output

M行,每行一个整数,依次表示询问对应的答案。

Sample Input

6
1 2 3 4 3 5
3
1 2
3 5
2 6

Sample Output

2
2
4
莫队
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
char buf[10000000], *ptr = buf - 1;
inline int readint(){
    int f = 1, n = 0;
    char ch = *++ptr;
    while(ch < '0' || ch > '9'){
        if(ch == '-') f = -1;
        ch = *++ptr;
    }
    while(ch <= '9' && ch >= '0'){
        n = (n << 1) + (n << 3) + ch - '0';
        ch = *++ptr;
    }
    return f * n;
}
const int maxn = 50000 + 10, maxm = 200000 + 10;
int n, m, size;
int num[maxn];
struct Node{
    int l, r, blk, id;
    Node(){}
    Node(int _l, int _r, int _id){
        l = _l;
        r = _r;
        blk = (l - 1) / size + 1;
        id = _id;
    }
    bool operator < (const Node &x) const {
        return blk == x.blk ? r < x.r : blk < x.blk;
    }
}a[maxm];
int cnt[1000000 + 10] = {0};
int L, R, ans = 0;
inline void inc(int w){
    cnt[num[w]]++;
    if(cnt[num[w]] == 1) ans++;
}
inline void dec(int w){
    cnt[num[w]]--;
    if(cnt[num[w]] == 0) ans--;
}
int op[maxm];
int main(){
    fread(buf, sizeof(char), sizeof(buf), stdin);
    n = readint();
    size = ceil(sqrt(n));
    for(int i = 1; i <= n; i++)
        num[i] = readint();
    m = readint();
    for(int l, r, i = 1; i <= m; i++){
        l = readint();
        r = readint();
        a[i] = Node(l, r, i);
    }
    sort(a + 1, a + m + 1);
    L = 1;
    R = 0; 
    for(int i = 1; i <= m; i++){
        while(R < a[i].r) R++, inc(R);
        while(R > a[i].r) dec(R), R--;
        while(L < a[i].l) dec(L), L++;
        while(L > a[i].l) L--, inc(L);
        op[a[i].id] = ans;
    }
    for(int i = 1; i <= m; i++)
        printf("%d\n", op[i]);
    return 0;
}

 

posted @ 2017-09-20 21:52  jzyy  阅读(148)  评论(0编辑  收藏  举报