Cod sursa(job #978742)

Utilizator FlameingoAiordachioaei Marius Flameingo Data 29 iulie 2013 16:31:43
Problema Heavy Path Decomposition Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 3.47 kb
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

const int NMAX = 100003;
vector <int> A[NMAX], C[NMAX];
int V[NMAX], n[NMAX], t[NMAX], cl[NMAX], sa[NMAX], aint[NMAX << 2], d[NMAX], L, k, _l, _r, rv;
bool viz[NMAX];

void DFS (const int nod) {

    viz[nod] = 1;
    int mn;
    bool f = 1;
    for (vector <int> :: iterator i = A[nod].begin (); i != A[nod].end (); ++i) {
        if (viz[*i])
            continue;
        n[*i] = n[nod] + 1;
        t[*i] = nod;
        DFS (*i);
        if (f)
            mn = *i,
            f = 0;
        else
            if (sa[*i] > sa[mn])
                mn = *i;
        sa[nod] += sa[*i];
    }
    if (f) {
        ++sa[nod];
        cl[nod] = ++L;
        C[L].push_back (nod);
        return;
    }
    C[cl[mn]].push_back (nod);
    cl[nod] = cl[mn];

}

void AINT_build (const int l, const int r, const int nod) {

    if (l == r) {
        aint[nod + d[k]] = V[C[k][l]];
        return;
    }
    int m = l + r >> 1;
    AINT_build (l, m, nod << 1);
    AINT_build (m + 1, r, (nod << 1) + 1);
    aint[nod + d[k]] = max (aint[(nod << 1) + d[k]], aint[(nod << 1) + 1 + d[k]]);

}

void build () {

    DFS (1);
    int i;
    for (k = 1; k <= L; ++k) {
        i = C[k].size ();
        reverse (C[k].begin (), C[k].end ());
        d[k + 1] = d[k] + (i << 1) - 1;
        AINT_build (0, i - 1, 1);
    }

}

void AINT_query (const int l, const int r, const int nod) {

    if (_r < l || _l > r)
        return;
    if (_l <= l && _r >= r) {
        if (aint[nod + d[k]] > rv)
            rv = aint[nod + d[k]];
        return;
    }
    int m = l + r >> 1;
    AINT_query (l, m, nod << 1);
    AINT_query (m + 1, r, (nod << 1) + 1);

}

void AINT_update (const int l, const int r, int const nod) {

    if (l == r) {
        aint[nod + d[k]] = _r;
        return;
    }
    int m = l + r >> 1;
    if (_l <= m)
        AINT_update (l, m, nod << 1);
    else
        AINT_update (m + 1, r, (nod << 1) + 1);
    aint[nod + d[k]] = max (aint[(nod << 1) + d[k]], aint[(nod << 1) + 1 + d[k]]);

}

int main () {

    freopen ("heavypath.in", "r", stdin);
    freopen ("heavypath.out", "w", stdout);
    int i, N, M, a, b, mt, w;
    scanf ("%d%d", &N, &M);
    for (i = 1; i <= N; ++i)
        scanf ("%d", &V[i]);
    for (i = 1; i < N; ++i)
        scanf ("%d%d", &a, &b),
        A[a].push_back (b),
        A[b].push_back (a);

    n[1] = 1;
    build ();
    while (M--) {
        scanf ("%d%d%d", &w, &a, &b);
        if (w) {
            mt = 0;
            while (cl[a] != cl[b]) {
                if (n[C[cl[a]][0]] < n[C[cl[b]][0]])
                    swap (a, b);
                k = cl[a];
                rv = 0;
                _l = 0;
                _r = n[a] - n[C[cl[a]][0]];
                AINT_query (0, C[k].size () - 1, 1);
                a = t[C[cl[a]][0]];
                if (rv > mt)
                    mt = rv;
            }
            if (n[a] > n[b])
                swap (a, b);
            k = cl[a];
            rv = 0;
            _l = n[a] - n[C[cl[a]][0]];
            _r = n[b] - n[C[cl[b]][0]];
            AINT_query (0, C[k].size () - 1, 1);
            if (rv > mt)
                mt = rv;
            printf ("%d\n", mt);
            continue;
        }
        k = cl[a];
        _l = n[a] - n[C[cl[a]][0]];
        _r = b;
        AINT_update (0, C[k].size () - 1, 1);
    }
}