Cod sursa(job #1184452)

Utilizator andreiiiiPopa Andrei andreiiii Data 12 mai 2014 19:23:04
Problema Guvern Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.96 kb
#include <algorithm>
#include <cstdio>
#include <set>
#include <vector>

using namespace std;

const int Nmax = 200005;

vector <int> G[Nmax], G1[Nmax];
int A[Nmax], First[Nmax], Last[Nmax], Dp[Nmax], Nr[Nmax];
int N, K;

struct comp {
    bool operator() (const int &a, const int &b)
    {
        return A[a] < A[b];
    }
};

struct comp1 {
    bool operator() (const int &a, const int &b)
    {
        return Last[a] < Last[b];
    }
};

set <int, comp> S;

void Dfs(const int node, const int father)
{
    if(father) G[node].erase(find(G[node].begin(), G[node].end(), father));

    set <int>::iterator it = S.upper_bound(node);
    if(it == S.end()) G1[0].push_back(node);
    else G1[*it].push_back(node);

    First[node] = ++K;
    S.insert(node);

    for(auto p: G[node])
        Dfs(p, node);

    Last[node] = ++K;
    S.erase(node);
}

void Dfs1(const int node)
{
    for(auto p: G1[node]) Dfs1(p);

    sort(G1[node].begin(), G1[node].end(), comp1());

    int N = G1[node].size();
    for(int i = 0; i < N; i++)
    {
        Dp[i] = 0;

        int j, step;
        for(step = 1; step < i; step <<= 1);

        for(j = -1; step; step >>= 1)
        {
            if(j + step < i) if(Last[G1[node][j + step]] < First[G1[node][i]])
                j += step;
        }

        if(i > 0) Dp[i] = max(Dp[i], Dp[i - 1]);
        if(j > -1) Dp[i] = max(Dp[i], Dp[j] + Nr[G1[node][i]]);
        else Dp[i] = max(Dp[i], Nr[G1[node][i]]);

        Nr[node] = max(Nr[node], Dp[i]);
    }

    Nr[node]++;
}

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);

        G[x].push_back(y);
        G[y].push_back(x);
    }

    for(int i = 1; i <= N; i++)
        scanf("%d", &A[i]);

    Dfs(1, 0);

    Dfs1(0);

    printf("%d\n", Nr[0] - 1);
}