#include <bits/stdc++.h>
using namespace std;
#define dbg(x) x
#define prt(x) dbg(cerr << x)
#define pv(x) dbg(cerr << #x << " = " << x << '\n')
#define pv2(x) dbg(cerr << #x << " = " << x.first << ',' << x.second << '\n')
#define parr(x) dbg(prt(#x << " = { "); for (auto y : x) prt(y << ' '); prt("}\n");)
#define parr2(x) dbg(prt(#x << " = { "); for (auto [y, z] : x) prt(y << ',' << z << " "); prt("}\n");)
#define parr2d(x) dbg(prt(#x << ":\n"); for (auto arr : x) {parr(arr);} prt('\n'));
#define parr2d2(x) dbg(prt(#x << ":\n"); for (auto arr : x) {parr2(arr);} prt('\n'));
const int lg = 20;
/*
tree
block nodes 1 by 1
on each move:
block a node
if you block the node with the cat on it
the cat moves to the MAXIMUM REACHABLE NODE
goal is make cat move as much as possible
note that whatever node you are at, you always have a number of subgraphs
you can break off into
pick the subgraph that yields you the best answer when you go to the max
value inside it
this is kind of the equivalent of blocking every other subgraph, then blocking
this node so you end up in the subgraph you chose
for (each subgraph)
dp[node] = max(dp[node], dp[subgraph] + dist(node, max in subgraph))
how do you get the max in subgraph though
same algo as centroid
if we can impl this in n^2, we get like 31 points
other special cases: path, binary tree
n^2:
find the max within the given subgraphs with a centroid-like dnc, except with
more layers
optimize n^2:
maybe reconstruct the "centroid" (really the maxvals) tree
but you still kinda need to find the max node in each subgraph
that is the bottleneck here
how to quickly find the max node in a subgraph?
also maybe you can like add the nodes back to the tree in order
starting with an empty graph
and maybe you can tell like when a node's component is a proper subgraph?
always is
and you are always adding the max to the subgraph...
so you always do dsu
*/
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int n;
cin >> n;
vector<int> p(n), at(n);
for (int i = 0; i < n; i++) {
cin >> p[i];
p[i]--;
at[p[i]] = i;
}
vector<vector<int>> edges(n);
bool path = true;
for (int i = 0; i < n - 1; i++) {
int x, y;
cin >> x >> y;
x--; y--;
if (y != x + 1) path = false;
edges[x].push_back(y);
edges[y].push_back(x);
}
if (path) {
vector<vector<int>> rmq(n, vector<int>(lg, 0));
for (int i = 0; i < n; i++) {
rmq[i][0] = p[i];
}
for (int j = 1; j < lg; j++) {
for (int i = 0; i < n - (1 << j) + 1; i++) {
rmq[i][j] = max(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
}
}
function<int(int, int)> rmx = [&] (int l, int r) {
int p2 = 31 - __builtin_clz(r - l + 1);
return max(rmq[l][p2], rmq[r - (1 << p2) + 1][p2]);
};
vector<long long> best(n, 0);
function<void(int, int, int)> dnc = [&] (int l, int r, int k) {
if (k != l) {
int kl = at[rmx(l, k - 1)];
dnc(l, k - 1, kl);
best[k] = max(best[k], best[kl] + k - kl);
}
if (k != r) {
int kr = at[rmx(k + 1, r)];
dnc(k + 1, r, kr);
best[k] = max(best[k], best[kr] + kr - k);
}
};
dnc(0, n - 1, at[n - 1]);
cout << best[at[n - 1]] << '\n';
} else {
vector<int> dep(n, 0), tpar(n, 0);
vector<long long> ans(n, 0);
function<void(int, int)> dfs_dep = [&] (int node, int par) {
tpar[node] = par;
for (auto next : edges[node]) {
if (next == par) continue;
dep[next] = dep[node] + 1;
dfs_dep(next, node);
}
};
dfs_dep(at[n - 1], at[n - 1]);
vector<vector<int>> anc(n, vector<int>(lg, 0));
for (int i = 0; i < n; i++) {
anc[i][0] = tpar[i];
}
for (int j = 1; j < lg; j++) {
for (int i = 0; i < n; i++) {
anc[i][j] = anc[anc[i][j - 1]][j - 1];
}
}
function<int(int, int)> kth_anc = [&] (int node, int k) {
for (int i = lg - 1; i >= 0; i--) {
if (1 << i <= k) {
node = anc[node][i];
k -= 1 << i;
}
}
return node;
};
function<int(int, int)> dist = [&] (int x, int y) {
if (dep[x] > dep[y]) swap(x, y);
int ret = dep[y] - dep[x];
y = kth_anc(y, dep[y] - dep[x]);
if (x == y) return ret;
for (int i = lg - 1; i >= 0; i--) {
if (anc[x][i] != anc[y][i]) {
x = anc[x][i];
y = anc[y][i];
ret += 1 << (i + 1);
}
}
return ret + 2;
};
vector<int> sz(n, 1), grp(n), mx = p;
iota(grp.begin(), grp.end(), 0);
function<int(int)> rep = [&] (int i) {
while (i != grp[i]) i = grp[i] = grp[grp[i]];
return i;
};
function<void(int, int)> merge = [&] (int i, int j) {
i = rep(i);
j = rep(j);
if (i == j) return;
if (sz[i] < sz[j]) swap(i, j);
sz[i] += sz[j];
grp[j] = i;
mx[i] = max(mx[i], mx[j]);
};
for (int i = 0; i < n; i++) {
int node = at[i], cmx = -1;
for (auto next : edges[node]) {
if (p[next] > p[node]) continue;
ans[node] = max(ans[node], ans[at[mx[rep(next)]]] + dist(at[mx[rep(next)]], node));
}
for (auto next : edges[node]) {
if (p[next] > p[node]) continue;
merge(next, node);
}
}
long long res = 0;
for (int i = 0; i < n; i++) {
res = max(res, ans[i]);
}
cout << res << '\n';
}
}
Compilation message
Main.cpp: In function 'int main()':
Main.cpp:161:25: warning: unused variable 'cmx' [-Wunused-variable]
161 | int node = at[i], cmx = -1;
| ^~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
0 ms |
348 KB |
Output is correct |
3 |
Correct |
1 ms |
604 KB |
Output is correct |
4 |
Correct |
0 ms |
348 KB |
Output is correct |
5 |
Correct |
0 ms |
348 KB |
Output is correct |
6 |
Correct |
0 ms |
348 KB |
Output is correct |
7 |
Correct |
1 ms |
600 KB |
Output is correct |
8 |
Correct |
0 ms |
344 KB |
Output is correct |
9 |
Correct |
0 ms |
348 KB |
Output is correct |
10 |
Correct |
0 ms |
348 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
0 ms |
348 KB |
Output is correct |
3 |
Correct |
1 ms |
604 KB |
Output is correct |
4 |
Correct |
0 ms |
348 KB |
Output is correct |
5 |
Correct |
0 ms |
348 KB |
Output is correct |
6 |
Correct |
0 ms |
348 KB |
Output is correct |
7 |
Correct |
1 ms |
600 KB |
Output is correct |
8 |
Correct |
0 ms |
344 KB |
Output is correct |
9 |
Correct |
0 ms |
348 KB |
Output is correct |
10 |
Correct |
0 ms |
348 KB |
Output is correct |
11 |
Correct |
0 ms |
348 KB |
Output is correct |
12 |
Correct |
0 ms |
348 KB |
Output is correct |
13 |
Correct |
1 ms |
348 KB |
Output is correct |
14 |
Correct |
0 ms |
344 KB |
Output is correct |
15 |
Correct |
0 ms |
348 KB |
Output is correct |
16 |
Correct |
0 ms |
344 KB |
Output is correct |
17 |
Correct |
0 ms |
348 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
0 ms |
348 KB |
Output is correct |
3 |
Correct |
1 ms |
604 KB |
Output is correct |
4 |
Correct |
0 ms |
348 KB |
Output is correct |
5 |
Correct |
0 ms |
348 KB |
Output is correct |
6 |
Correct |
0 ms |
348 KB |
Output is correct |
7 |
Correct |
1 ms |
600 KB |
Output is correct |
8 |
Correct |
0 ms |
344 KB |
Output is correct |
9 |
Correct |
0 ms |
348 KB |
Output is correct |
10 |
Correct |
0 ms |
348 KB |
Output is correct |
11 |
Correct |
0 ms |
348 KB |
Output is correct |
12 |
Correct |
0 ms |
348 KB |
Output is correct |
13 |
Correct |
1 ms |
348 KB |
Output is correct |
14 |
Correct |
0 ms |
344 KB |
Output is correct |
15 |
Correct |
0 ms |
348 KB |
Output is correct |
16 |
Correct |
0 ms |
344 KB |
Output is correct |
17 |
Correct |
0 ms |
348 KB |
Output is correct |
18 |
Correct |
4 ms |
2140 KB |
Output is correct |
19 |
Correct |
3 ms |
1884 KB |
Output is correct |
20 |
Correct |
3 ms |
1848 KB |
Output is correct |
21 |
Correct |
2 ms |
1372 KB |
Output is correct |
22 |
Correct |
2 ms |
1372 KB |
Output is correct |
23 |
Correct |
2 ms |
1332 KB |
Output is correct |
24 |
Correct |
2 ms |
1372 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
0 ms |
348 KB |
Output is correct |
3 |
Correct |
1 ms |
604 KB |
Output is correct |
4 |
Correct |
0 ms |
348 KB |
Output is correct |
5 |
Correct |
0 ms |
348 KB |
Output is correct |
6 |
Correct |
0 ms |
348 KB |
Output is correct |
7 |
Correct |
1 ms |
600 KB |
Output is correct |
8 |
Correct |
0 ms |
344 KB |
Output is correct |
9 |
Correct |
0 ms |
348 KB |
Output is correct |
10 |
Correct |
0 ms |
348 KB |
Output is correct |
11 |
Correct |
0 ms |
348 KB |
Output is correct |
12 |
Correct |
0 ms |
348 KB |
Output is correct |
13 |
Correct |
1 ms |
348 KB |
Output is correct |
14 |
Correct |
0 ms |
344 KB |
Output is correct |
15 |
Correct |
0 ms |
348 KB |
Output is correct |
16 |
Correct |
0 ms |
344 KB |
Output is correct |
17 |
Correct |
0 ms |
348 KB |
Output is correct |
18 |
Correct |
4 ms |
2140 KB |
Output is correct |
19 |
Correct |
3 ms |
1884 KB |
Output is correct |
20 |
Correct |
3 ms |
1848 KB |
Output is correct |
21 |
Correct |
2 ms |
1372 KB |
Output is correct |
22 |
Correct |
2 ms |
1372 KB |
Output is correct |
23 |
Correct |
2 ms |
1332 KB |
Output is correct |
24 |
Correct |
2 ms |
1372 KB |
Output is correct |
25 |
Correct |
0 ms |
348 KB |
Output is correct |
26 |
Correct |
3 ms |
1884 KB |
Output is correct |
27 |
Correct |
3 ms |
1884 KB |
Output is correct |
28 |
Correct |
3 ms |
1884 KB |
Output is correct |
29 |
Correct |
3 ms |
1884 KB |
Output is correct |
30 |
Correct |
3 ms |
1372 KB |
Output is correct |
31 |
Correct |
3 ms |
1372 KB |
Output is correct |
32 |
Correct |
5 ms |
1492 KB |
Output is correct |
33 |
Correct |
3 ms |
1372 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
0 ms |
348 KB |
Output is correct |
3 |
Correct |
1 ms |
604 KB |
Output is correct |
4 |
Correct |
0 ms |
348 KB |
Output is correct |
5 |
Correct |
0 ms |
348 KB |
Output is correct |
6 |
Correct |
0 ms |
348 KB |
Output is correct |
7 |
Correct |
1 ms |
600 KB |
Output is correct |
8 |
Correct |
0 ms |
344 KB |
Output is correct |
9 |
Correct |
0 ms |
348 KB |
Output is correct |
10 |
Correct |
0 ms |
348 KB |
Output is correct |
11 |
Correct |
0 ms |
348 KB |
Output is correct |
12 |
Correct |
0 ms |
348 KB |
Output is correct |
13 |
Correct |
1 ms |
348 KB |
Output is correct |
14 |
Correct |
0 ms |
344 KB |
Output is correct |
15 |
Correct |
0 ms |
348 KB |
Output is correct |
16 |
Correct |
0 ms |
344 KB |
Output is correct |
17 |
Correct |
0 ms |
348 KB |
Output is correct |
18 |
Correct |
4 ms |
2140 KB |
Output is correct |
19 |
Correct |
3 ms |
1884 KB |
Output is correct |
20 |
Correct |
3 ms |
1848 KB |
Output is correct |
21 |
Correct |
2 ms |
1372 KB |
Output is correct |
22 |
Correct |
2 ms |
1372 KB |
Output is correct |
23 |
Correct |
2 ms |
1332 KB |
Output is correct |
24 |
Correct |
2 ms |
1372 KB |
Output is correct |
25 |
Correct |
117 ms |
63500 KB |
Output is correct |
26 |
Correct |
112 ms |
61528 KB |
Output is correct |
27 |
Correct |
124 ms |
61660 KB |
Output is correct |
28 |
Correct |
106 ms |
41600 KB |
Output is correct |
29 |
Correct |
112 ms |
41808 KB |
Output is correct |
30 |
Correct |
109 ms |
41776 KB |
Output is correct |
31 |
Correct |
115 ms |
42068 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
0 ms |
348 KB |
Output is correct |
3 |
Correct |
231 ms |
45432 KB |
Output is correct |
4 |
Correct |
237 ms |
45640 KB |
Output is correct |
5 |
Correct |
225 ms |
45392 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
0 ms |
348 KB |
Output is correct |
3 |
Correct |
1 ms |
604 KB |
Output is correct |
4 |
Correct |
0 ms |
348 KB |
Output is correct |
5 |
Correct |
0 ms |
348 KB |
Output is correct |
6 |
Correct |
0 ms |
348 KB |
Output is correct |
7 |
Correct |
1 ms |
600 KB |
Output is correct |
8 |
Correct |
0 ms |
344 KB |
Output is correct |
9 |
Correct |
0 ms |
348 KB |
Output is correct |
10 |
Correct |
0 ms |
348 KB |
Output is correct |
11 |
Correct |
0 ms |
348 KB |
Output is correct |
12 |
Correct |
0 ms |
348 KB |
Output is correct |
13 |
Correct |
1 ms |
348 KB |
Output is correct |
14 |
Correct |
0 ms |
344 KB |
Output is correct |
15 |
Correct |
0 ms |
348 KB |
Output is correct |
16 |
Correct |
0 ms |
344 KB |
Output is correct |
17 |
Correct |
0 ms |
348 KB |
Output is correct |
18 |
Correct |
4 ms |
2140 KB |
Output is correct |
19 |
Correct |
3 ms |
1884 KB |
Output is correct |
20 |
Correct |
3 ms |
1848 KB |
Output is correct |
21 |
Correct |
2 ms |
1372 KB |
Output is correct |
22 |
Correct |
2 ms |
1372 KB |
Output is correct |
23 |
Correct |
2 ms |
1332 KB |
Output is correct |
24 |
Correct |
2 ms |
1372 KB |
Output is correct |
25 |
Correct |
0 ms |
348 KB |
Output is correct |
26 |
Correct |
3 ms |
1884 KB |
Output is correct |
27 |
Correct |
3 ms |
1884 KB |
Output is correct |
28 |
Correct |
3 ms |
1884 KB |
Output is correct |
29 |
Correct |
3 ms |
1884 KB |
Output is correct |
30 |
Correct |
3 ms |
1372 KB |
Output is correct |
31 |
Correct |
3 ms |
1372 KB |
Output is correct |
32 |
Correct |
5 ms |
1492 KB |
Output is correct |
33 |
Correct |
3 ms |
1372 KB |
Output is correct |
34 |
Correct |
117 ms |
63500 KB |
Output is correct |
35 |
Correct |
112 ms |
61528 KB |
Output is correct |
36 |
Correct |
124 ms |
61660 KB |
Output is correct |
37 |
Correct |
106 ms |
41600 KB |
Output is correct |
38 |
Correct |
112 ms |
41808 KB |
Output is correct |
39 |
Correct |
109 ms |
41776 KB |
Output is correct |
40 |
Correct |
115 ms |
42068 KB |
Output is correct |
41 |
Correct |
0 ms |
348 KB |
Output is correct |
42 |
Correct |
0 ms |
348 KB |
Output is correct |
43 |
Correct |
231 ms |
45432 KB |
Output is correct |
44 |
Correct |
237 ms |
45640 KB |
Output is correct |
45 |
Correct |
225 ms |
45392 KB |
Output is correct |
46 |
Correct |
283 ms |
58896 KB |
Output is correct |
47 |
Correct |
294 ms |
58784 KB |
Output is correct |
48 |
Correct |
283 ms |
60532 KB |
Output is correct |
49 |
Correct |
294 ms |
58924 KB |
Output is correct |
50 |
Correct |
277 ms |
45756 KB |
Output is correct |
51 |
Correct |
278 ms |
45856 KB |
Output is correct |
52 |
Correct |
288 ms |
45668 KB |
Output is correct |
53 |
Correct |
254 ms |
45832 KB |
Output is correct |