Pagini recente » Borderou de evaluare (job #132585) | Borderou de evaluare (job #2891611) | Borderou de evaluare (job #1557734) | Borderou de evaluare (job #1845500) | Cod sursa (job #2607110)
#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;
}