Cod sursa(job #2607110)

Utilizator MiricaMateiMirica Matei MiricaMatei Data 29 aprilie 2020 11:42:15
Problema Guvern Scor 60
Compilator cpp-64 Status done
Runda why Marime 1.76 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 200005;

struct Interval {
  int l, r, c;
  bool operator <(const Interval& other) const {
    return r < other.r;
  }
} a[MAXN];

int n;
vector<int>G[MAXN];
int v[MAXN];
set<pair<int, int> >s;
vector<int>up[MAXN];
int l[MAXN], r[MAXN], k;
int dp[MAXN];
int aib[2 * MAXN];

void update(int pos, int val) {
  for (; pos <= 2 * n; pos += (pos &- pos))
    aib[pos] = max(aib[pos], val);
}

int query(int pos) {
  int ans = 0;
  for (; pos; pos -= (pos & -pos))
    ans = max(ans, aib[pos]);
  return ans;
}

void res(int pos) {
  for (; pos <= 2 * n; pos += (pos & -pos))
    aib[pos] = 0;
}

void dfs(int node, int papa) {
  l[node] = ++k;
  if (node != 0)
    up[(*s.lower_bound({v[node], 0})).second].push_back(node);
  s.insert({v[node], node});
  for (auto it:G[node])
    if (it != papa)
      dfs(it, node);
  int m = 0;
  /*cerr << node << ':';
  for (auto it:up[node]) {
    cerr << it << ' ';
  }
  cerr << '\n';*/
  for (auto it:up[node])
    a[++m] = {l[it], r[it], dp[it]};
  sort(a + 1, a + m + 1);
  for (int i = 1; i <= m; ++i) {
     int val = query(a[i].l - 1) + a[i].c;
     dp[node] = max(dp[node], val);
     update(a[i].r, val);
  }
  for (int i = 1; i <= m; ++i)
    res(a[i].r);
  dp[node]++;
  s.erase({v[node], node});
  r[node] = ++k;

}

int main() {
  freopen("guvern.in", "r", stdin);
  freopen("guvern.out", "w", stdout);

  scanf("%d", &n);
  for (int i = 1; i < n; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    G[u].push_back(v);
    G[v].push_back(u);
  }
  G[0].push_back(1);

  v[0] = 2e9;
  for (int i = 1; i <= n; ++i)
    scanf("%d", &v[i]);

  dfs(0, 0);

  printf("%d\n", dp[0] - 1);

  return 0;
}