This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr int INF = numeric_limits<int>::max() / 2;
constexpr ll INFLL = numeric_limits<ll>::max() / 2;
template<class T>
istream &operator>>(istream &is, vector<T> &a) {
for (auto &i : a) {
is >> i;
}
return is;
}
vector<vector<int>> g;
constexpr int k = 18;
vector<vector<int>> up;
vector<int> tin, tout, depth;
int timer = 0;
void dfs1(int v, int p) {
tin[v] = timer++;
if (p != -1) {
depth[v] = depth[p] + 1;
up[0][v] = p;
for (int i = 1; i < k; ++i) {
up[i][v] = up[i - 1][up[i - 1][v]];
}
}
for (auto u : g[v]) {
if (u != p) {
dfs1(u, v);
}
}
tout[v] = timer;
}
bool is_anc(int p, int v) {
return tin[p] <= tin[v] && tout[v] <= tout[p];
}
int up_d(int v, int d) {
for (int i = k - 1; i >= 0; --i) {
if (d >= (1 << i)) {
v = up[i][v];
d -= (1 << i);
}
}
return v;
}
int LCA(int u, int v) {
if (depth[u] < depth[v]) {
swap(u, v);
}
u = up_d(u, depth[u] - depth[v]);
for (int i = k - 1; i >= 0; --i) {
if (up[i][u] != up[i][v]) {
u = up[i][u];
v = up[i][v];
}
}
if (u == v) {
return u;
}
return up[0][u];
}
int ans = -1;
int ansi = -1, ansj = -1;
void ckans(int u, int v, int c) {
if (ans < c) {
ans = c;
ansi = u;
ansj = v;
}
}
vector<array<int, 3>> paths;
vector<vector<int>> p1, p2; // eblany, vertical
vector<pair<int, int>> mn1, mn2; // depth and path (for vertical)
void ckmn(int v, pair<int, int> x) {
if (x.first <= mn1[v].first) {
mn2[v] = mn1[v];
mn1[v] = x;
} else if (x.first <= mn2[v].first) {
mn2[v] = x;
}
}
multiset<pair<int, int>> dfs2(int v, int p) {
for (auto i : p2[v]) {
int j = paths[i][2];
if (depth[j] <= depth[v]) {
ckmn(v, {depth[j], i});
}
}
multiset<pair<int, int>> cur;
for (auto i : p1[v]) {
int j = paths[i][1];
cur.insert({tin[j], i});
}
for (auto u : g[v]) {
if (u != p) {
auto x = dfs2(u, v);
if (mn1[u].first <= depth[v]) {
ckmn(v, mn1[u]);
}
if (mn2[u].first <= depth[v]) {
ckmn(v, mn2[u]);
}
if (x.size() < cur.size()) {
cur.swap(x);
}
for (auto [_, i] : x) {
auto [a, b, lca] = paths[i];
{
auto it = cur.lower_bound({tin[b], -1});
if (it != cur.end() && it->first <= tout[b]) {
ckans(i, it->second, depth[v] + depth[b] - 2 * depth[lca]);
}
}
for (int j = k - 1; j >= 0; --j) {
int subtr = up[j][b];
if (depth[subtr] >= depth[lca]) {
auto it = cur.lower_bound({tin[subtr], -1});
if (it == cur.end() || it->first > tout[subtr]) {
b = up[j][b];
}
}
}
if (b != lca) {
b = up[0][b];
auto it = cur.lower_bound({tin[b], -1});
assert(it != cur.end() && it->first <= tout[b]);
ckans(i, it->second, depth[v] + depth[b] - 2 * depth[lca]);
}
cur.insert({b, i});
}
}
}
ckans(mn1[v].second, mn2[v].second, depth[v] - mn2[v].first);
return cur;
}
int main() {
cin.tie(0)->sync_with_stdio(0);
#ifdef __APPLE__
freopen("input.txt", "r", stdin);
#endif
int n, q;
cin >> n >> q;
g.resize(n);
for (int i = 1; i < n; ++i) {
int p;
cin >> p;
--p;
g[i].push_back(p);
g[p].push_back(i);
}
tin.resize(n);
tout.resize(n);
depth.resize(n);
up.resize(k, vector<int>(n));
dfs1(0, -1);
paths.resize(q);
p1.resize(n);
p2.resize(n);
for (int i = 0; i < q; ++i) {
int u, v;
cin >> u >> v;
--u;
--v;
if (depth[u] < depth[v]) {
swap(u, v);
}
paths[i] = {u, v, LCA(u, v)};
p2[u].push_back(i);
if (!is_anc(v, u)) {
p1[u].push_back(i);
p2[v].push_back(i);
}
}
mn1.resize(n, {INF, -1});
mn2.resize(n, {INF, -1});
dfs2(0, -1);
if (ans == -1) {
cout << "0\n1 2\n";
} else {
cout << ans << "\n";
cout << ansi + 1 << " " << ansj + 1 << "\n";
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |