Submission #1318151

#TimeUsernameProblemLanguageResultExecution timeMemory
1318151ghos007Cat Exercise (JOI23_ho_t4)C++20
100 / 100
185 ms70932 KiB
//#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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...