Cod sursa(job #2477295)

Utilizator NicolaalexandraNicola Alexandra Mihaela Nicolaalexandra Data 19 octombrie 2019 22:27:22
Problema Guvern Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.42 kb
#include <fstream>
#include <vector>
#include <set>
#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;
int viz[DIM],v[DIM],dp[DIM],First[DIM],Last[DIM],E[DIM],w[DIM];
int n,i,x,y,k,el;
struct interval{
    int val,st,dr;
}intv[DIM];
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);
    } else g[0].push_back(nod);
    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){
    /// 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
    viz[nod] = 1;
    for (int i=0;i<L[nod].size();i++){
        int vecin = L[nod][i];
        if (!viz[vecin])
            dfs2 (vecin);
    }

    el = 0;
    for (int i=0;i<g[nod].size();i++){
        int vecin = g[nod][i];
        intv[++el] = {dp[vecin],First[vecin],Last[vecin]};
    }
    sort (intv+1,intv+el+1,cmp);
    for (int i=1;i<=el;i++){
        /// trb sa caut cel mai din dreapta interval care se termina inainte sa inceapa intv curent
        int poz = 0;
        int st = 1, 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] = max (w[i-1],w[poz]+intv[i].val);
    }
    dp[nod] = w[el];
    if (nod)
        dp[nod]++;
}
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];
        dp[i] = 1;
    }
    L[0].push_back(1);
    dfs (1,0);
    dfs2 (0);

    int sol = 0;
    for (i=0;i<=n;i++)
        sol = max (sol,dp[i]);
    fout<<sol;


    return 0;
}