Cod sursa(job #971491)

Utilizator FlameingoAiordachioaei Marius Flameingo Data 9 iulie 2013 13:58:55
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.03 kb
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

const int DMAX = 100004;
vector <int> A[DMAX], D[DMAX];
int V[DMAX], *aint[DMAX], E[DMAX << 1], I[DMAX], Dp[DMAX << 1], rmq[19][DMAX << 1], l2[DMAX << 1], s = 1, _s, cD[DMAX], cP[DMAX], F[DMAX], lft, rght, pz, _mx;
bool viz[DMAX];

int _max (const int a, const int b) {

    return V[a] > V[b] ? a : b;

}

int _min (const int a, const int b) {

    return Dp[a] > Dp[b] ? b : a;

}

void DFS (const int nod, const int dep) {

    bool k = 1;
    viz[nod] = 1;
    D[s].push_back (nod);
    cD [nod] = s;
    cP [nod] = D[s].size ();
    E[++_s] = nod;
    I[nod] = _s;
    Dp[_s] = dep;
    rmq[0][_s] = _s;
    l2 [_s + 1] = l2 [(_s + 1) >> 1] + 1;
    int i;
    for (i = 0; i < A[nod].size (); ++i)
        if (!viz[A[nod][i]])
            F[A[nod][i]] = nod,
            DFS (A[nod][i], dep + 1),
            k = 0,
            E[++_s] = nod,
            I[nod] = _s,
            Dp[_s] = dep,
            rmq[0][_s] = _s,
            l2 [_s + 1] = l2 [(_s + 1) >> 1] + 1;

    if (k)
        ++s;


}

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

    if (l == r) {
        aint[s][nod] = D[s][l];
        return;
    }
    int m = (l + r) >> 1;
    AINT_line_build (l, m, nod * 2);
    AINT_line_build (m + 1, r, nod * 2 + 1);
    aint[s][nod] = _max (aint[s][nod * 2], aint[s][nod * 2 + 1]);

}

void AINT_build () {

    for (--s; s >= 1; --s) {
        aint[s] = new int[2 * (D[s].size () + 1)];
        AINT_line_build (0, D[s].size () - 1, 1);
    }

}

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

    if (lft <= l && r <= rght) {
        if (V[_mx] < V[aint[pz][nod]])
            _mx = aint[pz][nod];
        return;
    }
    if (lft > r || rght < l)
        return;
    int m = (l + r) >> 1;
    AINT_query (l, m, nod * 2);
    AINT_query (m + 1, r, nod * 2 + 1);

}

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

    if (l == r)
        return;
    int m = (l + r) >> 1;
    if (lft <= m)
        AINT_update (l, m, nod * 2);
    else
        AINT_update (m + 1, r, nod * 2 + 1);
    aint[pz][nod] = _max (aint[pz][nod * 2], aint[pz][nod * 2 + 1]);

}

void RMQ_build () {

    int j, l, n;
    for (int i = 1; (1 << i) <= _s; ++i)
        for (j = 1, n = _s - (1 << i) + 1, l = 1 << i - 1; j <= n; ++j)
            rmq[i][j] = _min (rmq[i - 1][j], rmq[i - 1][j + l]);


}

int RMQ_query (const int a, const int b) {

    int l = b - a + 1;
    return _min (rmq[l2[l]][a], rmq[l2[l]][a + l - (1 << l2[l])]);

}

int query (int nod1, int nod2) { //nod2 father nod1

    int mx = 0, k;
    while (cD[nod1] != cD[nod2]) {
        lft = 1;
        rght = cP[nod1];
        pz = cD[nod1];
        _mx = 0;
        AINT_query (1, D[pz].size (), 1);
        if (V[_mx] > V[mx])
            mx = _mx;
        nod1 = F[D[pz][0]];
    }
    _mx = 0;
    lft = cP[nod2];
    rght = cP[nod1];
    pz = cD[nod1];
    AINT_query (1, D[pz].size (), 1);
    if (V[_mx] > V[mx])
        mx = _mx;
    return mx;

}

void update (const int a) {

    pz = cD[a];
    lft = a;
    AINT_update (1, D[pz].size (), 1);

}

int main () {

    freopen ("heavypath.in", "r", stdin);
    freopen ("heavypath.out", "w", stdout);
    int N, M, i, a, b, lca;
    bool t;
    scanf ("%d%d", &N, &M);
    V[0] = -2e9;
    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);

    DFS (1, 0);
    AINT_build ();
    RMQ_build ();
    // E[RMQ_query (min(I[4], I[7]), max(I[4], I[7]))]
    while (M--) {
        scanf ("%d%d%d", &t, &a, &b);
        if (t) {
            if (I[a] > I[b])
                swap (a, b);
            lca = E[RMQ_query (I[a], I[b])];
            printf ("%d\n", V[_max (query (a, lca), query (b, lca))]);
        }
        else
            V[a] = b,
            update (a);

    }

}