-
Notifications
You must be signed in to change notification settings - Fork 50
/
Copy path911G. Mass Change Queries.cpp
103 lines (81 loc) · 2.04 KB
/
911G. Mass Change Queries.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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
Idea:
- Segment Tree.
- In the beginning each element `x` equal to its value,
and after each query the element with value `x` will
change to be equal to `y`.
- To maintain the previous effect we can use any data
structure like Segment Tree, each node in the segment
tree contains the mapping between the real values and
the current values.
- We should use lazy propagation to pass the time limit.
*/
#include <bits/stdc++.h>
using namespace std;
int const N = 2e5 + 1, M = 1e2 + 1;
int n, q, s, e, x, y, tar, a[N], seg[4 * N][M], lazy[4 * N];
void build(int at, int l, int r) {
for(int i = 1; i < M; ++i)
seg[at][i] = i;
if(l == r)
return;
int mid = (l + r) >> 1;
build(at << 1, l, mid);
build(at << 1 | 1, mid + 1, r);
}
void pro(int at, int l, int r) {
if(l != r) {
lazy[at << 1] = lazy[at << 1 | 1] = 1;
for(int i = 1; i < M; ++i)
seg[at << 1][i] = seg[at][seg[at << 1][i]],
seg[at << 1 | 1][i] = seg[at][seg[at << 1 | 1][i]];
lazy[at] = 0;
for(int i = 1; i < M; ++i)
seg[at][i] = i;
}
}
void update(int at, int l, int r) {
if(lazy[at] != 0)
pro(at, l, r);
if(l > e || r < s)
return;
if(l >= s && r <= e) {
lazy[at] = 1;
for(int i = 1; i < M; ++i)
if(seg[at][i] == x)
seg[at][i] = y;
pro(at, l, r);
return;
}
int mid = (l + r) >> 1;
update(at << 1, l, mid);
update(at << 1 | 1, mid + 1, r);
}
int get(int at, int l, int r) {
if(lazy[at] != 0)
pro(at, l, r);
if(l > e || r < s)
return 0;
if(l >= s && r <= e)
return seg[at][tar];
int mid = (l + r) >> 1;
return get(at << 1, l, mid) + get(at << 1 | 1, mid + 1, r);
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d", a + i);
build(1, 1, n);
scanf("%d", &q);
for(int i = 0; i < q; ++i) {
scanf("%d %d %d %d", &s, &e, &x, &y);
update(1, 1, n);
}
for(int i = 1; i <= n; ++i) {
s = e = i;
tar = a[i];
printf("%s%d", i == 1 ? "" : " ", get(1, 1, n));
}
puts("");
return 0;
}