[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
1 2 3 4 3 5
3
1 2
3 5
2 6
Sample Output
2
2
4
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; }