Cod sursa(job #1643500)

Utilizator bogdan10bosBogdan Sitaru bogdan10bos Data 9 martie 2016 19:04:07
Problema Guvern Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.46 kb
#include <bits/stdc++.h>

using namespace std;

#define FILE_IO
#define fs first
#define sc second

typedef pair <int, int> pii;
typedef pair <pii, int> piii;

const int buffer = 1 << 13;
int cnt = buffer - 1;
char buff[buffer + 5];
char gchar()
{
    if(++cnt == buffer)
    {
        cnt = 0;
        fread(buff, buffer, 1, stdin);
    }
    return buff[cnt];
}
int gint()
{
    int sgn = 1;
    char ch = gchar();
    while(ch < '0' || '9' < ch)
    {
        if(ch == '-')   sgn = -1;
        ch = gchar();
    }
    int x = 0;
    while('0' <= ch && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = gchar();
    }
    return (x * sgn);
}

int n, I, ans;
int val[200005], ord[200005], need[200005];
int intrv[200005][2];
int dp[200005];
int indp[200005];
piii rec[200005];
vector <int> edg[200005];
vector <int> nxtdp[200005];
map <int, int> mp;

int aib[200005];
void U(int pos, int val)
{
    for(int i = pos; i <= n; i += (i & (-i)))
        aib[i] += val;
}

int Q(int pos)
{
    int ans = 0;
    for(int i = pos; i >= 1; i -= (i & (-i)))
        ans += aib[i];
    return ans;
}

int aibsearch(int val)
{
    int pos = 0, sum = 0;
    for(int bit = 18; bit >= 0; bit--)
        if( pos + (1 << bit) <= n && sum + aib[pos + (1 << bit)] < val )
            sum += aib[pos + (1 << bit)], pos += 1 << bit;
    return pos + 1;
}

bool cmp(int a, int b)
{
    return val[a] < val[b];
}

void DFS(int nod, int fth)
{
    int needval = Q(val[nod]);
    int needpos = aibsearch(needval + 1);
    need[nod] = ord[ needpos ];
    nxtdp[ need[nod] ].push_back(nod);

    U(val[nod], 1);
    intrv[nod][0] = ++I;

    for(vector <int> :: iterator it = edg[nod].begin(); it != edg[nod].end(); it++)
    {
        int nxt = *it;
        if(nxt == fth) continue;
        DFS(nxt, nod);
    }

    U(val[nod], -1);
    intrv[nod][1] = ++I;
}

void dpDFS(int nod, int fth)
{
    for(vector <int> :: iterator it = edg[nod].begin(); it != edg[nod].end(); it++)
    {
        int nxt = *it;
        if(nxt == fth) continue;
        dpDFS(nxt, nod);
    }

    int k = 0;
    for(vector <int> :: iterator it = nxtdp[nod].begin(); it != nxtdp[nod].end(); it++)
    {
        int nxt = *it;
        rec[++k] = { {intrv[nxt][1], intrv[nxt][0]}, dp[nxt] };
    }

    sort(rec + 1, rec + k + 1);
    for(int i = 1; i <= k; i++)
    {
        int val = rec[i].sc;
        int lmt = rec[i].fs.sc;
        indp[i] = max(indp[i - 1], val);

        int p = 1;
        int u = i - 1;
        while(p <= u)
        {
            int mij = p + (u - p) / 2;
            if(rec[mij].fs.fs < lmt)
            {
                indp[i] = max(indp[i], indp[mij] + val);
                p = mij + 1;
            }
            else
                u = mij - 1;
        }
    }

    dp[nod] = 1 + indp[k];
}

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

    n = gint();
    for(int i = 1; i < n; i++)
    {
        int x = gint();
        int y = gint();
        edg[x].push_back(y);
        edg[y].push_back(x);
    }

    for(int i = 1; i <= n; i++)
    {
        val[i] = gint();
        ord[i] = i;
    }
    sort(ord + 1, ord + n + 1, cmp);
    for(int i = 1; i <= n; i++)
        val[ ord[i] ] = i;

    DFS(1, 0);
    edg[0].push_back(1);
    dpDFS(0, 0);

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

    return 0;
}