1. 程式人生 > >BZOJ 1878 [SDOI2009]HH的項鏈 【莫隊】

BZOJ 1878 [SDOI2009]HH的項鏈 【莫隊】

mit std 所表 urn mem 表達 \n script pac

任意門:https://www.lydsy.com/JudgeOnline/problem.php?id=1878

1878: [SDOI2009]HH的項鏈

Time Limit: 4 Sec Memory Limit: 64 MB
Submit: 7548 Solved: 3718
[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

解題思路:

莫隊裸題,轉移的時候判斷數字是否唯一即可。

AC code:

 1 #include <bits/stdc++.h>
 2
using namespace std; 3 const int MAXN = 5e4+10; 4 const int MAXU = 1e6+10; 5 const int MAXQ = 2e5+10; 6 int N, M, lim; 7 int sum[MAXU]; 8 int a[MAXN]; 9 int ans[MAXQ]; 10 struct Query 11 { 12 int l, r, id; 13 }Q[MAXQ]; 14 15 bool cmp(Query a, Query b){ 16 int la = a.l/lim, lb = b.l/lim; 17
if(la != lb) return la < lb; 18 return a.r < b.r; 19 } 20 21 int Move(int x, int v) 22 { 23 int res = 0; 24 if(v == 1 && sum[a[x]] == 0) res++; 25 if(v == -1 && sum[a[x]] == 1) res--; 26 sum[a[x]]+=v; 27 return res; 28 } 29 30 int main() 31 { 32 scanf("%d", &N); 33 for(int i = 1; i <= N; i++){ 34 scanf("%d", &a[i]); 35 } 36 lim = sqrt(N); 37 scanf("%d", &M); 38 for(int i = 1; i <= M; i++){ 39 scanf("%d %d", &Q[i].l, &Q[i].r); 40 Q[i].id = i; 41 } 42 43 sort(Q+1, Q+1+M, cmp); 44 45 int cur = 0, L = 1, R = 0; 46 for(int i = 1; i <= M; i++){ 47 while(Q[i].l < L) cur+=Move(--L, 1); 48 while(Q[i].l > L) cur+=Move(L++, -1); 49 while(Q[i].r < R) cur+=Move(R--, -1); 50 while(Q[i].r > R) cur+=Move(++R, 1); 51 ans[Q[i].id] = cur; 52 } 53 54 for(int i = 1; i <= M; i++){ 55 printf("%d\n", ans[i]); 56 } 57 58 return 0; 59 60 }

BZOJ 1878 [SDOI2009]HH的項鏈 【莫隊】