Cod sursa(job #1464888)

Utilizator TeodorescuStefanEduardTeodorescu Stefan Eduard TeodorescuStefanEduard Data 25 iulie 2015 22:11:24
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.54 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;
}