-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmo's_algorithm.cpp
executable file
·70 lines (55 loc) · 1.31 KB
/
mo's_algorithm.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
const int N = 3e4 + 9, M = 2e5 + 9, oo = 0x3f3f3f3f, Mod = 1e9 + 7;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int BLK = 256;
struct query {
int l, r, id, blk;
query() = default;
query(int _l, int _r, int _id) {
l = _l;
r = _r;
id = _id;
blk = l / BLK;
}
bool operator < (const query other) const {
if(blk ^ other.blk)
return blk < other.blk;
return (blk & 1) ? r < other.r : r > other.r;
}
} queries[M];
int res[M], freq[M << 3], cur;
void add(int id) {
cur += (++freq[id] == 1);
}
void remove(int id) {
cur -= (--freq[id] == 0);
}
int get_res() {
return cur;
}
int cur_l, cur_r, l, r, n, q, a[N];
void Solve() {
cin >> n;
for(int i = 1; i <= n; ++i) cin >> a[i];
cin >> q;
for(int i = 1; i <= q; ++i) {
cin >> l >> r;
queries[i] = query(l, r, i);
}
sort(queries + 1, queries + 1 + q);
cur_l = 1, cur_r = 0; // assign to right invalid index
for(int i = 1; i <= q; ++i) {
int ql = queries[i].l;
int qr = queries[i].r;
// Add right
while(cur_r < qr) add(a[++cur_r]);
// Add left
while(cur_l > ql) add(a[--cur_l]);
// Remove right
while(cur_r > qr) remove(a[cur_r--]);
// Remove left
while(cur_l < ql) remove(a[cur_l++]);
res[queries[i].id] = get_res();
}
for(int i = 1; i <= q; ++i)
cout << res[i] << "\n";
}