Cod sursa(job #2458289)

Utilizator lucametehauDart Monkey lucametehau Data 20 septembrie 2019 09:39:55
Problema Guvern Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.53 kb
#include <fstream>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;

ifstream cin ("guvern.in");
ofstream cout ("guvern.out");

struct Nod {
  int st, dr, val;
  bool operator < (const Nod &other) const {
    return dr < other.dr;
  }
} a[200005];

int n, x, y, cnt;

int v[200005], fst[200005], lst[200005];
int dp[200005], dp2[200005];
vector <int> g[200005], gr[200005];
set <pair <int, int>> s;

int search(int val, int m) {
  int st = 1, dr = m, mid;
  while(st <= dr) {
    mid = (st + dr) >> 1;
    if(a[mid].dr < val)
      st = mid + 1;
    else
      dr = mid - 1;
  }
  return dr;
}
int calcDp(int nod) {
  int m = 0;
  for(auto &nod2 : gr[nod])
    a[++m] = {fst[nod2], lst[nod2], dp[nod2]};
  sort(a + 1, a + m + 1);
  for(int i = 1; i <= m; i++)
    dp2[i] = max(dp2[i - 1], a[i].val + dp2[search(a[i].st, m)]);
  return dp2[m];
}

void dfs(int nod, int father) {
  int nod2 = (*s.lower_bound(make_pair(v[nod], 0))).second;
  gr[nod2].push_back(nod);
  fst[nod] = ++cnt;
  s.insert(make_pair(v[nod], nod));
  for(auto &son : g[nod]) {
    if(son != father)
      dfs(son, nod);
  }
  lst[nod] = ++cnt;
  s.erase(make_pair(v[nod], nod));
  dp[nod] = 1 + calcDp(nod);
}

int main() {
  cin >> n;
  for(int i = 1; i < n; i++) {
    cin >> x >> y;
    g[x].push_back(y);
    g[y].push_back(x);
  }
  for(int i = 1; i <= n; i++)
    cin >> v[i];
  dfs(1, 0);
  int ans = 0;
  for(int i = 1; i <= n; i++)
    ans = max(ans, dp[i]);
  cout << ans;
  return 0;
}