Cod sursa(job #1880397)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 15 februarie 2017 18:46:26
Problema Guvern Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.2 kb
#include <fstream>
#include <cstring>
#include <set>
#include <algorithm>

using namespace std;

ofstream fout ("guvern.out");

class InputReader {
	public:
        InputReader() {}
        InputReader(const char *name) {
            fin = fopen(name, "r");
			buffpos = Size - 1;
        }
        inline InputReader &operator >>(int &n) {
			char ch = nextpos();
            while((ch < '0' || ch > '9') && ch != '-') {
                ch = nextpos();
            }

            int semn = 1;
            if (ch == '-') {
                semn = -1; ch = nextpos();
            }

            n = 0;
            while('0' <= ch && ch <= '9') {
                n = n * 10 + ch - '0';
                ch = nextpos();
            }
            n *= semn;
            return *this;
        }
    private:
        FILE *fin;
        static const int Size = 1 << 17;
        int buffpos;
        char buff[Size];

        inline char nextpos() {
            ++ buffpos;
            if(buffpos == Size) {
                buffpos = 0;
                fread(buff, Size, 1, fin);
            }
			return buff[ buffpos ];
        }
} fin ("guvern.in");

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

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

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 );
    } else {
        l[ 0 ].push_back( nod );
    }
    s.insert(make_pair(v[ nod ], nod));

    first[ nod ] = ++ m;
    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 ] = m;
}

int suma (int i) {
    set< pair<int, int> >::iterator it = s.lower_bound(make_pair(first[ i ], 0)), auxit;

    int sum = 0;
    while (it != s.end() && it -> first <= last[ i ]) {
        sum += it -> second;
        auxit = it;
        ++ it;
        s.erase( auxit );
    }
    return sum;
}

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

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

    d[ nod ] = 0;

    s.clear();

    for (int j = l[ nod ].size() - 1; j >= 0; -- j) {
        int i = l[ nod ][ j ];
        d[ i ] = max(d[ i ], suma( i ));

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

    d[ nod ] = suma( nod ) + 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 ];
    }

    dfs( 1 );

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

    s.clear();
    for (int j = l[ 0 ].size() - 1; j >= 0; -- j) {
        int i = l[ 0 ][ j ];
        d[ i ] = max(d[ i ], suma( i ));

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

    first[ 0 ] = 0; last[ 0 ] = n + 1;
    d[ 0 ] = suma( 0 );
    sol = max(sol, d[ 0 ]);

    fout << sol << "\n";

    fout.close();
    return 0;
}