Pagini recente » Cod sursa (job #2701300) | Cod sursa (job #662815) | Cod sursa (job #1192424) | Cod sursa (job #2491971) | Cod sursa (job #2477286)
#include <fstream>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#define DIM 200010
#define INF 2000000000
using namespace std;
ifstream fin ("guvern.in");
ofstream fout ("guvern.out");
vector <int> L[DIM],g[DIM];
set < pair<int,int> > s;
map <int,int> f;
int t[DIM],v[DIM],dp[DIM],First[DIM],Last[DIM],E[DIM],w[DIM];
int n,i,x,y,k,el;
struct interval{
int val,st,dr;
}intv[DIM];
void dfs (int nod, int tata){
E[++k] = nod;
First[nod] = k;
set < pair<int,int> > :: iterator it = s.lower_bound(make_pair(v[nod],0));
if (it != s.end()){
/// inseamna ca pe nod pot sa il leg de x
int x = it->second;
g[x].push_back(nod);
} else g[0].push_back(nod);
s.insert (make_pair(v[nod],nod));
for (int i=0;i<L[nod].size();i++){
int vecin = L[nod][i];
if (vecin != tata)
dfs (vecin,nod);
}
s.erase(s.find(make_pair(v[nod],nod)));
Last[nod] = k;
}
inline int cmp (interval a, interval b){
return a.dr < b.dr;
}
void dfs2 (int nod, int tata){
/// pot sa aleg doar dintre fiii care sunt legati direct de nod
/// si nu am voie sa iau 2 noduri si unul sa fie stramosul altuia
/// => pb spectacolelor pe intervalele din parcurgerea euler
for (int i=0;i<L[nod].size();i++){
int vecin = L[nod][i];
if (vecin != tata)
dfs2 (vecin,nod);
}
if (g[nod].size()){
el = 0;
for (int i=0;i<g[nod].size();i++){
int vecin = g[nod][i];
intv[++el] = {dp[vecin],First[vecin],Last[vecin]};
}
sort (intv+1,intv+el+1,cmp);
w[1] = intv[1].val;
for (int i=2;i<=el;i++){
/// trb sa caut cel mai din dreapta interval care se termina inainte sa inceapa intv curent
int poz = -1;
int st = 1, dr = i-1;
while (st <= dr){
int mid = (st+dr)>>1;
if (intv[mid].dr < intv[i].st){
poz = mid;
st = mid+1;
} else dr = mid-1;
}
w[i] = w[i-1];
if (poz != -1)
w[i] = max (w[i],w[poz]+intv[i].val);
}
dp[nod] = w[el];
if (nod)
dp[nod]++;
}}
int main (){
fin>>n;
for (i=1;i<n;i++){
fin>>x>>y;
L[x].push_back(y);
L[y].push_back(x);
}
for (i=1;i<=n;i++){
fin>>v[i];
dp[i] = 1;
}
L[0].push_back(1);
dfs (1,0);
dfs2 (0,0);
int sol = 0;
for (i=0;i<=n;i++)
sol = max (sol,dp[i]);
fout<<sol;
return 0;
}