Pagini recente » Cod sursa (job #572943) | Cod sursa (job #407708) | Cod sursa (job #1365306) | Cod sursa (job #1565011) | Cod sursa (job #2477279)
#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;
struct interval{
int val,st,dr;
};
vector <interval> intv;
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);
t[nod] = f[x];
}
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()){
intv.clear();
for (int i=0;i<g[nod].size();i++){
int vecin = g[nod][i];
intv.push_back({dp[vecin],First[vecin],Last[vecin]});
}
sort (intv.begin(),intv.end(),cmp);
w[0] = intv[0].val;
for (int i=1;i<intv.size();i++){
/// trb sa caut cel mai din dreapta interval care se termina inainte sa inceapa intv curent
int poz = -1;
int st = 0, 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[intv.size()-1] + 1;
}}
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];
t[i] = -1, dp[i] = 1;
}
dfs (1,0);
dfs2 (1,0);
int sol = 0;
for (i=1;i<=n;i++)
sol = max (sol,dp[i]);
fout<<sol;
return 0;
}