BZOJ 1878: [SDOI2009]HH的项链
1878: [SDOI2009]HH的项链
Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 3548 Solved: 1757
[Submit][Status][Discuss]
Description
HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此, 他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同 的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只好求助睿智的你,来解 决这个问题。
Input
第一行:一个整数N,表示项链的长度。 第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。 第三行:一个整数M,表示HH询问的个数。 接下来M行:每行两个整数,L和R(1 ≤ L ≤ R ≤ N),表示询问的区间。
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
HINT
对于20%的数据,N ≤ 100,M ≤ 1000;
对于40%的数据,N ≤ 3000,M ≤ 200000;
对于100%的数据,N ≤ 50000,M ≤ 200000。
Source
OTZ NEIGHTHORN
树状数组O(NlogN) 或 莫队算法O(N^1.5)
1 #include <bits/stdc++.h> 2 3 /* SCANNER */ 4 5 #define siz 1024 6 7 inline int get_c(void) 8 { 9 static char buf[siz]; 10 static char *head = buf + siz; 11 static char *tail = buf + siz; 12 13 if (head == tail) 14 fread(head = buf, 1, siz, stdin); 15 16 return *head++; 17 } 18 19 inline int get_i(void) 20 { 21 register int ret = 0; 22 register int neg = false; 23 register int bit = get_c(); 24 25 for (; bit < 48; bit = get_c()) 26 if (bit == '-')neg ^= true; 27 28 for (; bit > 47; bit = get_c()) 29 ret = ret * 10 + bit - 48; 30 31 return neg ? -ret : ret; 32 } 33 34 #define N 50005 35 #define M 200005 36 #define V 1000005 37 38 int n, m; 39 int num[N]; 40 41 /* PREWORK */ 42 43 int nxt[N]; 44 int lst[V]; 45 int fst[V]; 46 47 /* QUERY */ 48 49 int lt[M]; 50 int rt[M]; 51 int ans[M]; 52 int ord[M]; 53 54 inline bool cmp(int a, int b) 55 { 56 return lt[a] < lt[b]; 57 } 58 59 /* B I T */ 60 61 int tree[N]; 62 63 inline void add(int p, int k) 64 { 65 for (; p <= n; p += p&-p) 66 tree[p] += k; 67 } 68 69 inline int ask(int p) 70 { 71 int ret = 0; 72 for (; p >= 1; p -= p&-p) 73 ret += tree[p]; 74 return ret; 75 } 76 77 /* MAIN */ 78 79 signed main(void) 80 { 81 n = get_i(); 82 83 for (int i = 1; i <= n; ++i) 84 num[i] = get_i(); 85 86 for (int i = 0; i < V; ++i) 87 lst[i] = n + 1; 88 89 for (int i = n; i >= 1; --i) 90 nxt[i] = lst[num[i]], lst[num[i]] = i; 91 92 for (int i = 1; i <= n; ++i) 93 if (!fst[num[i]]) 94 { 95 add(i, 1); 96 fst[num[i]] = 1; 97 } 98 99 m = get_i(); 100 101 for (int i = 1; i <= m; ++i) 102 { 103 ord[i] = i; 104 lt[i] = get_i(); 105 rt[i] = get_i(); 106 } 107 108 std::sort(ord + 1, ord + 1 + m, cmp); 109 110 int left = 1; 111 112 for (int i = 1; i <= m; ++i) 113 { 114 while (left < lt[ord[i]]) 115 { 116 add(left, -1); 117 add(nxt[left], 1); 118 ++left; 119 } 120 121 ans[ord[i]] = ask(rt[ord[i]]); 122 } 123 124 for (int i = 1; i <= m; ++i) 125 printf("%d\n", ans[i]); 126 }
@Author: YouSiki