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
104
105
106
107
108
109
|
const int N = 1e5 + 10;
const int B = 3500;
const int L = N / B + 10;
int n, m, q;
int a[N], b[N], cors[N];
int f[L][N], cnnt, id[N], LLL[N], RRR[N];
bool used[N];
vector <int> g[N];
bitset <N> reach[N];
void init () {
for (int i = 1; i <= cnnt; i ++) {
LLL[i] = RRR[i - 1] + 1;
RRR[i] = min (n, LLL[i] + B - 1);
for (int j = LLL[i]; j <= RRR[i]; j ++) id[j] = i;
}
}
void upd (int block) {
int l = LLL[block], r = RRR[block];
for (int i = 1; i <= n; i ++) f[block][i] = 0;
for (int i = n; i; i --) {
if (a[i] >= l && a[i] <= r && !used[i]) chkmax (f[block][i], b[i]);
for (const auto& v : g[i]) chkmax (f[block][i], f[block][v]);
}
}
void prework () {
for (int i = n; i; i --) {
reach[i][i] = true;
for (const auto& v : g[i]) reach[i] |= reach[v];
}
cnnt = (n + B - 1) / B;
init ();
}
int usdp[N], Cnt, sta, stb;
void push (int x) {
if (!used[x]) {
used[x] = true;
usdp[++ Cnt] = x;
}
}
int query (int x, int l, int r, auto& ca, auto& cb, int tim) {
for (; sta < ca.size ();) {
auto [x, y, t] = ca[sta];
if (t > tim) break;
swap (a[x], a[y]), cors[a[x]] = x, cors[a[y]] = y;
sta ++;
}
for (; stb < cb.size ();) {
auto [x, y, t] = cb[stb];
if (t > tim) break;
swap (b[x], b[y]);
stb ++;
}
int ans = 0, L = id[l], R = id[r];
auto getinfo = [&](int L, int R) {
for (int i = L; i <= R; i ++)
if (reach[x][cors[i]]) chkmax (ans, b[ cors[i] ]);
};
if (L == R) getinfo (l, r);
else {
getinfo (l, RRR[L]);
for (int i = L + 1; i < R; i ++) chkmax (ans, f[i][x]);
getinfo (LLL[R], r);
}
for (int i = 1; i <= Cnt; i ++) if (reach[x][ usdp[i] ] && a[usdp[i]] >= l && a[usdp[i]] <= r) chkmax (ans, b[ usdp[i] ]);
return ans;
}
void solve (auto& ca, auto& cb, auto& qry) {
for (auto& [x, y, t] : ca) push (x), push (y);
for (auto& [x, y, t] : cb) push (x), push (y);
for (int i = 1; i <= cnnt; i ++) upd (i);
for (const auto& [x, l, r, i] : qry) printf ("%d\n", query (x, l, r, ca, cb, i));
for (; sta < ca.size (); sta ++) {auto [x, y, t] = ca[sta]; swap (a[x], a[y]), cors[a[x]] = x, cors[a[y]] = y;}
for (; stb < cb.size (); stb ++) {auto [x, y, t] = cb[stb]; swap (b[x], b[y]);}
sta = stb = 0;
Cnt = 0;
for (auto& [x, y, t] : ca) used[x] = used[y] = false;
for (auto& [x, y, t] : cb) used[x] = used[y] = false;
ca.clear (), cb.clear (), qry.clear ();
}
void work () {
for (int i = 1; i <= n; i ++) g[i].clear (), reach[i].reset ();
scanf ("%d%d%d", &n, &m, &q);
for (int i = 1, u, v; i <= m; i ++) scanf ("%d%d", &u, &v), g[u].push_back (v);
for (int i = 1; i <= n; i ++) scanf ("%d", &a[i]), cors[a[i]] = i;
for (int i = 1; i <= n; i ++) scanf ("%d", &b[i]);
prework ();
int cnt = 0;
vector < tuple <int, int, int> > a, b;
vector < tuple <int, int, int, int> > qry;
for (int i = 1; i <= q; i ++) {
int opt, x, l, r;
scanf ("%d%d%d", &opt, &x, &l);
if (opt == 1) a.emplace_back (x, l, i);
if (opt == 2) b.emplace_back (x, l, i);
if (opt == 3) scanf ("%d", &r), qry.emplace_back (x, l, r, i);
if ((++ cnt) == B) solve (a, b, qry), cnt = 0;
}
if (cnt) solve (a, b, qry), cnt = 0;
}
|