#include <bits/stdc++.h>
using namespace std;
const int maxn = 200005;
const int max_log = 18;
const int inf = 1000000000;
int n;
vector<int> g[maxn];
int depth[maxn];
long long dp[maxn];
int permutation[maxn];
int jump[maxn][max_log];
void dfs(int node, int par, int dep)
{
depth[node] = dep;
for (auto next_node : g[node])
{
if (next_node != par)
{
jump[next_node][0] = node;
dfs(next_node, node, dep + 1);
}
}
}
void build_sparse()
{
jump[1][0] = 1;
for (int i = 1; i <= max_log - 1; ++i)
{
for (int j = 1; j <= n; ++j)
{
jump[j][i] = jump[jump[j][i - 1]][i - 1];
}
}
}
int find_lca(int x, int y)
{
if (depth[x] < depth[y])
{
swap(x, y);
}
int diff = depth[x] - depth[y];
for (int i = 0; i <= max_log - 1; ++i)
{
if ((diff & (1 << i)) != 0)
{
x = jump[x][i];
diff -= (1 << i);
if (diff == 0)
{
break;
}
}
}
if (x == y)
{
return x;
}
for (int i = max_log - 1; i >= 0; --i)
{
if (jump[x][i] != jump[y][i])
{
x = jump[x][i];
y = jump[y][i];
}
}
return jump[x][0];
}
int find_dist(int x, int y)
{
return depth[x] + depth[y] - 2 * depth[find_lca(x, y)];
}
int parent[maxn];
int dsu_rank[maxn];
int component_current_root[maxn];
int find_root(int node)
{
if (parent[node] == node)
{
return node;
}
return parent[node] = find_root(parent[node]);
}
void connect(int x, int y)
{
x = find_root(x);
y = find_root(y);
if (x == y)
{
return;
}
if (dsu_rank[x] < dsu_rank[y])
{
swap(x, y);
}
if (dsu_rank[x] == dsu_rank[y])
{
++dsu_rank[x];
}
parent[x] = y;
}
void fastIO()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
int main()
{
fastIO();
cin >> n;
for (int i = 1; i <= n; ++i)
{
cin >> permutation[i];
}
for (int i = 1; i <= n - 1; ++i)
{
int x, y;
cin >> x >> y;
x = permutation[x];
y = permutation[y];
g[x].push_back(y);
g[y].push_back(x);
}
dfs(1, -1, 0);
for (int i = 1; i <= n; ++i)
{
dsu_rank[i] = 1;
parent[i] = i;
component_current_root[i] = i;
}
for (int node = 1; node <= n; ++node)
{
for (auto next_node : g[node])
{
if (next_node > node)
{
continue;
}
dp[node] = max(dp[node], dp[component_current_root[find_root(next_node)]] + find_dist(node, component_current_root[find_root(next_node)]));
connect(node, next_node);
}
component_current_root[find_root(node)] = node;
}
cout << dp[n] << endl;
return 0;
}
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
4948 KB |
Output is correct |
2 |
Incorrect |
2 ms |
4948 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
4948 KB |
Output is correct |
2 |
Incorrect |
2 ms |
4948 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
4948 KB |
Output is correct |
2 |
Incorrect |
2 ms |
4948 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
4948 KB |
Output is correct |
2 |
Incorrect |
2 ms |
4948 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
4948 KB |
Output is correct |
2 |
Incorrect |
2 ms |
4948 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
3 ms |
4948 KB |
Output is correct |
2 |
Incorrect |
2 ms |
5076 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
4948 KB |
Output is correct |
2 |
Incorrect |
2 ms |
4948 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |