Cod sursa(job #1828189)

Utilizator TimitocArdelean Andrei Timotei Timitoc Data 12 decembrie 2016 21:45:40
Problema Guvern Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.34 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
#define MAXN 200050

using namespace std;

int resp[MAXN], dp[MAXN], euler[2*MAXN], first[MAXN], last[MAXN];
int key[MAXN], parent[MAXN], n, nq;
struct cmp
{
    bool operator()(int x, int y)
    {
        return key[x] < key[y];
    }
};
vector<int> graf[MAXN];
vector<int> obl[MAXN];
set<int, cmp> s;

void read()
{
    scanf("%d", &n);
    for (int i = 1; i <= n-1; i++) {
        int x, y;
        scanf("%d %d", &x, &y);
        graf[x].push_back(y);
        graf[y].push_back(x);
    }
    for (int i = 1; i <= n; i++)
        scanf("%d", &key[i]);
}

void build(int nod)
{
    euler[++nq] = nod;
    first[nod] = last[nod] = nq;
    auto it = s.lower_bound(nod);
    if (it != s.end()) {
        resp[nod] = *it;
        obl[*it].push_back(nod);
    }
    else {
        resp[nod] = n+1;
        obl[n+1].push_back(nod);
    }
    s.insert(nod);
    for (int y : graf[nod]) {
        if (parent[nod] != y)
        {
            parent[y] = nod;
            build(y);
            euler[++nq] = nod;
            last[nod] = nq;
        }
    }
    s.erase(nod);
}

struct event
{
    int nod, tip, timp;
    event(int nod = 1, int tip = 0, int timp = 0) : nod(nod), tip(tip), timp(timp) { }
};
bool cmp(event x, event y)
{
    return x.timp < y.timp;
}
event e[2*MAXN];
int best[2*MAXN], ind[2*MAXN];
int rq;

void solve(int nod)
{
    for (int y : graf[nod])
        if (parent[y] == nod) {
            solve(y);
        }
    dp[nod] = 1;
    rq = 0;
    for (int y : obl[nod])
    {
        e[++rq] = event(y, 0, first[y]);
        e[++rq] = event(y, 1, last[y]);
        best[rq-1] = best[rq] = 0;
    }
    sort(e+1, e+1+rq, cmp);
    for (int i = 1; i <= rq; i++)
        if (e[i].tip == 1)
            ind[e[i].nod] = i;
    for (int i = 1; i <= rq; i++)
    {
        best[i] = max(best[i-1], best[i]);
        if (e[i].tip == 0)
            best[ind[e[i].nod]] = max(best[ind[e[i].nod]], best[i]+dp[e[i].nod]);
    }
    dp[nod] += best[rq];
}

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

    read();
    build(1);
    parent[1] = n+1;
    graf[n+1].push_back(1);
    solve(n+1);
    printf("%d", dp[n+1]-1);

    return 0;
}