#include<bits/stdc++.h>
#define taskname "C"
using namespace std;
typedef long long ll;
template<class T>void maximize(T& a, T b){
if(a < b){
a = b;
}
}
const int lim = 2e5 + 5;
int n, P[lim], A[lim], B[lim];
namespace sub123{
void solve(){
vector<vector<int>>p(n + 1, vector<int>(n + 1));
for(int i = 1; i <= n; i++){
p[i][i] = i;
for(int j = i + 1; j <= n; j++){
p[i][j] = (P[j] > P[p[i][j - 1]] ? j : p[i][j - 1]);
}
}
function<int(int, int)>dp;
dp = [&] (int l, int r){
int i = p[l][r];
return max(l == i ? 0 : dp(l, i - 1) + i - p[l][i - 1], r == i ? 0 : dp(i + 1, r) + p[i + 1][r] - i);
};
cout << dp(1, n);
}
}
namespace sub4567{
vector<int>g[lim];
int edge_vertex[lim], h[lim], up[lim][18];
void dfs_1(int s){
for(int& i : g[s]){
int d = A[i] ^ B[i] ^ s;
if(d != up[s][0]){
h[d] = h[up[d][0] = s] + 1;
for(int i = 1; i < 18; i++){
up[d][i] = up[up[d][i - 1]][i - 1];
}
dfs_1(d);
}
}
}
int lca(int u, int v){
if(h[u] < h[v]){
swap(u, v);
}
for(int k = h[u] - h[v], i = 0; i < 18; i++){
if(1 << i & k){
u = up[u][i];
}
}
if(u == v){
return u;
}
for(int i = 17; i > -1; i--){
if(up[u][i] != up[v][i]){
u = up[u][i];
v = up[v][i];
}
}
return up[u][0];
}
int distance(int u, int v){
return h[u] + h[v] - (h[lca(u, v)] << 1);
}
ll dfs_2(int s){
ll ans = 0;
for(int& i : g[s]){
int d = A[i] ^ B[i] ^ s;
if(P[s] > P[edge_vertex[i]]){
maximize(ans, ll(distance(s, edge_vertex[i])) + dfs_2(edge_vertex[i]));
}
}
return ans;
}
void solve(){
for(int i = 1; i < n; i++){
g[A[i]].emplace_back(i);
g[B[i]].emplace_back(i);
}
vector<int>vertex(n), lab(n + 1), max_lab(n + 1);
iota(vertex.begin(), vertex.end(), 1);
sort(vertex.begin(), vertex.end(), [&] (int i, int j){
return P[i] < P[j];
});
iota(lab.begin(), lab.end(), 0);
iota(max_lab.begin(), max_lab.end(), 0);
auto find_set = [&] (int N){
while(N != lab[N]){
N = lab[N] = lab[lab[N]];
}
return N;
};
auto merge = [&] (int u, int v){
lab[u = find_set(u)] = v = find_set(v);
if(P[max_lab[v]] < P[max_lab[u]]){
max_lab[v] = max_lab[u];
}
};
for(int& u : vertex){
for(int& i : g[u]){
int v = A[i] ^ B[i] ^ u;
if(P[u] > P[v]){
edge_vertex[i] = max_lab[v = find_set(v)];
merge(u, v);
}
}
}
memset(up, h[1] = 0, sizeof(up));
dfs_1(1);
cout << dfs_2(vertex.back());
}
}
int main(){
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
if(fopen(taskname".inp", "r")){
freopen(taskname".inp", "r", stdin);
}
cin >> n;
for(int i = 1; i <= n; i++){
cin >> P[i];
}
bool is_sub123 = true;
for(int i = 1; i < n; i++){
cin >> A[i] >> B[i];
if(A[i] != i && B[i] != i + 1){
is_sub123 = false;
}
}
if(n <= 5000 && is_sub123){
sub4567::solve();
}
else{
sub4567::solve();
}
}
Compilation message (stderr)
Main.cpp: In function 'int main()':
Main.cpp:118:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
118 | freopen(taskname".inp", "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
# | 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... |