Cod sursa(job #1879165)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 14 februarie 2017 19:12:24
Problema Guvern Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.57 kb
#include <fstream>
#include <cstring>
#include <set>
#include <algorithm>

using namespace std;

ifstream fin ("guvern.in"); ofstream fout ("guvern.out");

typedef vector< int > graf;

const int nmax = 2e5;

int n, sol;
bool viz[nmax + 1];
int v[nmax + 1], h[nmax + 1], d[nmax + 1], first[nmax + 1], last[nmax + 1];

int aib[nmax + 1];

graf g[nmax + 1];
vector< int > l[nmax + 1], df;

set< pair<int, int> > s;

void dfs (int nod) {
    set< pair<int, int> >::iterator it = s.lower_bound(make_pair(v[ nod ], 0));
    if (it != s.end()) {
        l[it -> second].push_back( nod );
    }
    s.insert(make_pair(v[ nod ], nod));

    df.push_back( nod );
    first[ nod ] = (int)df.size() - 1;
    viz[ nod ] = 1;

    for (auto i : g[ nod ]) {
        if (viz[ i ] == 0) {
            h[ i ] = h[ nod ] + 1;
            dfs( i );
        }
    }

    s.erase(make_pair(v[ nod ], nod));
    last[ nod ] = (int)df.size() - 1;
}

inline int lsb (int x) {
    return x & -x;
}

void update (int pos, int val) {
    for (int i = pos; i <= n; i += lsb( i )) {
        aib[ i ] += val;
    }
}

int query (int pos) {
    int ans = 0;
    for (int i = pos; i > 0; i -= lsb( i )) {
        ans += aib[ i ];
    }
    return ans;
}

inline bool cmp (int a, int b) {
    return (h[ a ] > h[ b ]);
}

void solve (int nod) {
    viz[ nod ] = 1;

    for (auto i : g[ nod ]) {
        if (viz[ i ] == 0) {
            solve( i );
        }
    }

    d[ nod ] = 0;
    sort(l[ nod ].begin(), l[ nod ].end(), cmp);

    while (!s.empty()) {
        update(s.begin() -> first, -(s.begin() -> second));
        s.erase(s.begin());
    }

    for (auto i : l[ nod ]) {
        int aux = query(last[ i ]) - query(first[ i ] - 1);
        d[ i ] = max(d[ i ], aux);

        set< pair<int, int> >::iterator it = s.lower_bound(make_pair(first[ i ], 0)), auxit;
        while (it != s.end() && it -> first <= last[ i ]) {
            update(it -> first, -(it->second));
            auxit = it;
            ++ it;
            s.erase( auxit );
        }

        update(first[ i ], d[ i ]);
        s.insert(make_pair(first[ i ], d[ i ]));
    }

    d[ nod ] = query(last[ nod ]) - query(first[ nod ] - 1) + 1;
    sol = max(sol, d[ nod ]);
}

int main() {
    fin >> n;
    for (int i = 1; i < n; ++ i) {
        int x, y;
        fin >> x >> y;
        g[ x ].push_back( y );
        g[ y ].push_back( x );
    }
    for (int i = 1; i <= n; ++ i) {
        fin >> v[ i ];
    }

    df.push_back( 0 );
    dfs( 1 );

    memset(viz, 0, sizeof(viz));
    sol = 0;
    solve( 1 );

    fout << sol << "\n";

    fin.close();
    fout.close();
    return 0;
}