题目传送门
1 /*
2 题意:从i开始,之前出现过的就是之前的值,否则递增,问第p个数字是多少
3 莫队算法:先把a[i+p-1]等效到最前方没有它的a[j],问题转变为求[l, r]上不重复数字有几个,裸莫队:)
4 */
5 #include <cstdio>
6 #include <algorithm>
7 #include <map>
8 #include <set>
9 #include <vector>
10 #include <cmath>
11 #include <cstring>
12 using namespace std;
13
14 const int MAXN = 2e6 + 10;
15 const int INF = 0x3f3f3f3f;
16 map<int, int> table;
17 vector<int> V[MAXN];
18 int cnt[MAXN];
19 int a[MAXN];
20 int ans[MAXN];
21 struct Data
22 {
23 int b, l, r, id;
24 Data () {}
25 Data (int b, int l, int r, int id) : b (b), l (l), r (r), id (id) {};
26 }data[MAXN];
27 int n, m;
28 int ret;
29
30 bool cmp(Data x, Data y)
31 {
32 if (x.b == y.b) return x.r < y.r;
33 else return x.b < y.b;
34 }
35
36 void updata(int v)
37 {
38 if (v == 1) ret++;
39 else if (v == 0) ret--;
40 }
41
42 void Modui(void)
43 {
44 sort (data+1, data+1+m, cmp);
45 memset (cnt, 0, sizeof (cnt));
46
47 int l = 1, r = 0; ret = 0;
48 for (int i=1; i<=m; ++i)
49 {
50 while (data[i].l < l)
51 {
52 ++cnt[a[--l]];
53 if (cnt[a[l]] == 1) ret++;
54 }
55 while (data[i].l > l)
56 {
57 --cnt[a[l]];
58 if (cnt[a[l]] == 0) ret--;
59 l++;
60 }
61 while (data[i].r > r)
62 {
63 ++cnt[a[++r]];
64 if (cnt[a[r]] == 1) ret++;
65 }
66 while (data[i].r < r)
67 {
68 --cnt[a[r]];
69 if (cnt[a[r]] == 0) ret--;
70 r--;
71 }
72
73 ans[data[i].id] = ret;
74 }
75
76 for (int i=1; i<=m; ++i)
77 {
78 printf ("%d
", ans[i]);
79 }
80 }
81
82 int main(void) //Gym - 100496D Data Mining
83 {
84 // freopen ("D.in", "r", stdin);
85 freopen ("data.in", "r", stdin);
86 freopen ("data.out", "w", stdout);
87
88 while (scanf ("%d", &n) == 1)
89 {
90 table.clear ();
91 for (int i=1; i<=n; ++i) V[i].clear ();
92
93 int num = 0;
94 for (int i=1; i<=n; ++i)
95 {
96 scanf ("%d", &a[i]);
97 a[i] = table[a[i]] ? table[a[i]] : table[a[i]] = ++num;
98 V[a[i]].push_back (i);
99 }
100
101 int block = (int) sqrt (n * 1.0);
102 scanf ("%d", &m);
103 for (int i=1; i<=m; ++i)
104 {
105 int l, r; scanf ("%d%d", &l, &r);
106 r = l + r - 1;
107 int pos = lower_bound (V[a[r]].begin (), V[a[r]].end (), l) - V[a[r]].begin ();
108 r = V[a[r]][pos];
109 data[i] = Data (l / block, l, r, i);
110 }
111
112 Modui ();
113 }
114
115 return 0;
116 }