Cod sursa(job #1413541)

Utilizator Stefex09Stefan Teodorescu Stefex09 Data 1 aprilie 2015 22:22:03
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.51 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>

using namespace std;

ifstream in ("heavypath.in");
ofstream out ("heavypath.out");

const int MAXN = 100010;

vector <int> Graf[MAXN];
int subTree[MAXN];
bool Viz[MAXN];
int Lvl[MAXN];
int V[MAXN];

void DFS (int nod)
{
    Viz[nod] = 1;
    subTree[nod] = 1;

    vector <int> :: iterator it;
    for (it = Graf[nod].begin (); it != Graf[nod].end (); ++ it)
        if (!Viz[*it]){
            Lvl[*it] = Lvl[nod] + 1;

            DFS (*it);
            subTree[nod] += subTree[*it];
        }
}

int nrLant;
int careLant[MAXN], lungLant[MAXN], tataLant[MAXN];
int incLant[MAXN], pozNod[MAXN];
vector <int> AINT[MAXN];

void DFS2 (int nod, int lant)
{
    ++ lungLant[lant];
    careLant[nod] = lant;
    pozNod[nod] = lungLant[lant];
    Viz[nod] = 1;

    vector <int> :: iterator it;
    int bestSub = 0;

    for (it = Graf[nod].begin (); it != Graf[nod].end (); ++ it)
        if (!Viz[*it])
            if (subTree[*it] > bestSub)
                bestSub = subTree[*it];


    for (it = Graf[nod].begin (); it != Graf[nod].end (); ++ it)
        if (!Viz[*it] && subTree[*it] == bestSub){
            DFS2 (*it, lant);
            break;
        }

    for (it = Graf[nod].begin (); it != Graf[nod].end (); ++ it)
        if (!Viz[*it]){
            ++ nrLant;
            incLant[nrLant] = *it;
            tataLant[nrLant] = nod;
            DFS2 (*it, nrLant);
        }
}

void update (int lant, int nod, int st, int dr, int poz, int val)
{
    if (st == dr){
        AINT[lant][nod] = val;
        return;
    }

    int mid = (st + dr) / 2;

    if (poz <= mid)
        update (lant, nod * 2, st, mid, poz, val);
    else
        update (lant, nod * 2 + 1, mid + 1, dr, poz, val);

    AINT[lant][nod] = max (AINT[lant][2 * nod], AINT[lant][2 * nod + 1]);
}

int query (int lant, int nod, int st, int dr, int A, int B)
{
    if (A > B)
        swap (A, B);

    if (A <= st && dr <= B)
        return AINT[lant][nod];

    int mid = (st + dr) / 2;
    int Ans = 0;

    if (A <= mid)
        Ans = max (Ans, query (lant, nod * 2, st, mid, A, B));
    if (mid < B)
        Ans = max (Ans, query (lant, nod * 2 + 1, mid + 1, dr, A, B));

    return Ans;
}

int Solve (int X, int Y)
{
    int Ans = 0;

    while (careLant[X] != careLant[Y]){
        if (Lvl[incLant[careLant[X]]] < Lvl[incLant[careLant[Y]]])
            swap (X, Y);

        Ans = max (Ans, query (careLant[X], 1, 1, lungLant[careLant[X]], 1, pozNod[X]));
        X = tataLant[careLant[X]];
    }

    Ans = max (Ans, query (careLant[X], 1, 1, lungLant[careLant[X]], pozNod[X], pozNod[Y]));
    return Ans;
}

int main()
{
    int N, M, i, op, a, b;

    in >> N >> M;
    for (i = 1; i <= N; i ++)
        in >> V[i];
    for (i = 1; i < N; i ++){
        in >> a >> b;
        Graf[a].push_back (b);
        Graf[b].push_back (a);
    }

    DFS (1);
    memset (Viz, 0, sizeof (Viz));
    incLant[++ nrLant] = 1;
    DFS2 (1, 1);

    for (i = 1; i <= nrLant; i ++)
        AINT[i].resize (4 * lungLant[i]);

    for (i = 1; i <= N; i ++)
        update (careLant[i], 1, 1, lungLant[careLant[i]], pozNod[i], V[i]);

    for (i = 1; i <= M; i ++){
        in >> op >> a >> b;

        if (op == 0){
            update (careLant[a], 1, 1, lungLant[careLant[a]], pozNod[a], b);
        }
        else{
            out << Solve (a, b) << "\n";
        }
    }

    return 0;
}