Cod sursa(job #1643271)

Utilizator geniucosOncescu Costin geniucos Data 9 martie 2016 18:18:47
Problema Guvern Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.06 kb
#include<set>
#include<cstdio>
#include<vector>
#include<algorithm>

using namespace std;

int nr, N, maxi, val[200009], need[200009], dp[200009], ap[200009], st[200009], dr[200009], bst[200009];
set < pair < int , int > > S;
vector < int > v[200009], fii[200009];
pair < pair < int , int > , int > ev[200009];

void dfs (int nod, int tata)
{
    set < pair < int , int > > :: iterator it = S.lower_bound (make_pair (val[nod], 0));
    if (it == S.end ()) need[nod] = 0;
    else need[nod] = it->second, fii[it->second].push_back (nod);
    S.insert (make_pair (val[nod], nod)), st[nod] = ++nr;
    for (vector < int > :: iterator it = v[nod].begin (); it != v[nod].end (); it ++)
        if (*it != tata) dfs (*it, nod);
    S.erase (make_pair (val[nod], nod)), dr[nod] = nr;
}

int solve2 ()
{
    int maxl = 0;
    sort (ev + 1, ev + nr + 1);
    for (int i=1; i<=nr; i++)
    {
        int p = 1, u = i - 1, mij, ras = 0, st = ev[i].first.second, dr = ev[i].first.first, cost = ev[i].second;
        while (p <= u)
        {
            mij = (p + u) >> 1;
            if (ev[mij].first.first < st) ras = mij, p = mij + 1;
            else u = mij - 1;
        }
        bst[i] = max (bst[i - 1], cost + bst[ras]);
    }
    return bst[nr];
}

void solve (int nod)
{
    ap[nod] = 1;
    for (vector < int > :: iterator it = fii[nod].begin (); it != fii[nod].end (); it ++)
        if (ap[*it] == 0) solve (*it);
    nr = 0;
    for (vector < int > :: iterator it = fii[nod].begin (); it != fii[nod].end (); it ++)
        ev[++nr] = make_pair (make_pair (dr[*it], st[*it]), dp[*it]);
    dp[nod] = 1 + solve2 ();
}

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

scanf ("%d", &N);
for (int i=1; i<N; i++)
{
    int x, y;
    scanf ("%d %d", &x, &y);
    v[x].push_back (y);
    v[y].push_back (x);
}
for (int i=1; i<=N; i++)
    scanf ("%d", &val[i]);
dfs (1, -1);
for (int i=1; i<=N; i++)
    if (need[i] == 0)
        solve (i), maxi = max (maxi, dp[i]);
printf ("%d\n", maxi);

return 0;
}