//#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 2e5 + 1;
const int MAXLOG = 21;
struct cnm {
vector <int> sz,pr,best_ans,mx,tmp;
cnm(int n) {
for (int i = 0;i < n;i++) {
sz.push_back(1);
pr.push_back(i);
best_ans.push_back(0);
mx.push_back(i);
}
}
int get(int u) {
if (pr[u] == u)return u;
return pr[u] = get(pr[u]);
}
void merge(int a,int b,int newcost) {
a = get(a);
b = get(b);
if (a == b) return;
if (sz[a] < sz[b]) {
swap(a,b);
}
pr[b] = a;
sz[a] += sz[b];
if (tmp[mx[a]] < tmp[mx[b]]) {
mx[a] = mx[b];
}
best_ans[a] = max({best_ans[a],newcost,best_ans[b]});
}
int get_mx(int u) {
u = get(u);
return mx[u];
}
};
int binup[MAXN][MAXLOG];
int tin[MAXN];
int tout[MAXN];
int t = 0;
void dfs(int u,int p,vector <vector <int>> &g) {
tin[u] = t++;
if (p == -1) {
for (int i = 0;i < MAXLOG;i++) {
binup[u][i] = u;
}
}else {
for (int i = 1;i < MAXLOG;i++) {
binup[u][i] = binup[binup[u][i-1]][i-1];
}
}
for (auto el : g[u]) {
if (el == p)continue;
binup[el][0] = u;
dfs(el,u,g);
}
tout[u] = t++;
}
bool is_ans(int a,int b) {
return tin[a] <= tin[b] && tout[a] >= tout[b];
}
int len(int a,int b) {
if (a == b)return 0;
if (is_ans(a,b))swap(a,b);
int ans = 0;
for (int i = MAXLOG - 1;i >= 0;i--) {
if (!is_ans(binup[a][i],b)) {
ans += (1ll << i);
a = binup[a][i];
}
}
a = binup[a][0];
ans++;
if (a == b)return ans;
swap(a,b);
for (int i = MAXLOG - 1;i >= 0;i--) {
if (!is_ans(binup[a][i],b)) {
ans += (1ll << i);
a = binup[a][i];
}
}
return ans + 1;
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
vector <int> vec(n);
int ind = -1;
for (int i = 0;i < n;i++) {
cin >> vec[i];
vec[i]--;
if (vec[i] == n-1) {
ind = i;
}
}
vector <vector <int>> g(n);
for (int i = 1;i < n;i++) {
int u,v;
cin >> u >> v;
u--;
v--;
g[u].push_back(v);
g[v].push_back(u);
}
vector <int> obxod(n);
for (int i = 0;i < n;i++) {
obxod[vec[i]] = i;
}
dfs(0,-1,g);
cnm cm(n);
cm.tmp = vec;
for (int i = 0;i < n;i++) {
int u = obxod[i];
for (auto el : g[u]) {
if (vec[el] > vec[u]) {
continue;
}
int plus = len(u,cm.get_mx(el));
cm.merge(u,el,plus + cm.best_ans[cm.get(el)]);
}
}
cout << cm.best_ans[cm.get(0)] << '\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... |