Pagini recente » Borderou de evaluare (job #1157814) | Borderou de evaluare (job #3312961) | Cod sursa (job #2276855) | Borderou de evaluare (job #1665465) | Cod sursa (job #3334697)
#include <fstream>
#include <vector>
#include <utility>
#include <algorithm>
#include <set>
#define int long long
using namespace std;
ifstream fcin("guvern.in");
ofstream fout("guvern.out");
int n,x,y,val[200005],dp[200005];
vector <int> v[200005],u[200005];
set < pair <int,int> > s;
int st[200005],dr[200005],nr;
inline void tour(int nod, int p)
{
st[nod]=++nr;
auto it=s.lower_bound({val[nod],0});
u[nod].emplace_back(it->second);
u[it->second].emplace_back(nod);
s.insert({val[nod],nod});
for(int i : v[nod]) if(i!=p)
tour(i,nod);
s.erase({val[nod],nod});
dr[nod]=nr;
}
struct elem
{
int st,dr,x;
bool operator<(const elem &x) const
{
if(dr==x.dr)
return st<x.st;
return dr<x.dr;
}
};
inline int cb(int x, int sz, vector <elem> &c)
{
int sol=0;
for(int i=(1<<20); i>0; i>>=1)
if((sol|i)<sz && c[sol|i].dr<x) sol|=i;
return sol;
}
inline int solve(vector <elem> &c)
{
if(c.empty()) return 0;
sort(c.begin(), c.end());
vector <int> dp(c.size()+2, 0);
for(int i=0; i<c.size(); i++)
dp[i+1]=max(dp[i],dp[cb(c[i].st,i,c)]+c[i].x);
return dp[c.size()];
}
inline void dfs(int nod, int p)
{
vector <elem> c;
for(int i : u[nod]) if(i!=p)
dfs(i,nod), c.push_back({st[i],dr[i],dp[i]});
dp[nod]=solve(c)+1;
}
signed main()
{
fcin>>n;
for(int i=1; i<n; i++)
{
fcin>>x>>y;
v[x].emplace_back(y);
v[y].emplace_back(x);
}
for(int i=1; i<=n; i++)
fcin>>val[i];
tour(1,0);
dfs(1,0);
int rez=0;
for(int i=1; i<=n; i++)
rez=max(rez,dp[i]);
fout<<rez;
return 0;
}