Cod sursa(job #1143127)

Utilizator Alexghita96Ghita Alexandru Alexghita96 Data 14 martie 2014 19:40:21
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.56 kb
#include <cstdio>
#include <vector>
#include <algorithm>

#define Nmax 100005
#define INF 0x3f3f3f3f

using namespace std;

int N, M, nrp = 1;
int V[Nmax], Place[Nmax], Poz[Nmax];
int Viz[Nmax], W[Nmax], H[Nmax], Used[Nmax], T[Nmax];
vector <int> G[Nmax], Lant[Nmax], Arb[Nmax];

struct Comp
{
    bool operator()(int a, int b)
    {
        if (W[a] > W[b])
            return true;
        return false;
    }
};

void Citire()
{
    int x, y;
    scanf("%d %d", &N, &M);
    for (int i = 1; i <= N; ++i)
    {
        scanf("%d", &V[i]);
        W[i] = 1;
    }
    for (int i = 1; i <= N - 1; ++i)
    {
        scanf("%d %d", &x, &y);
        G[x].push_back(y);
        G[y].push_back(x);
    }
}

void DFS(int nod, int h)
{
    vector <int> :: iterator it;
    Viz[nod] = 1;
    H[nod] = h;
    for (it = G[nod].begin(); it != G[nod].end(); ++it)
        if (!Viz[*it])
        {
            DFS(*it, h + 1);
            W[nod] += W[*it];
        }
}

void Lanturi(int nod, int nr)
{
    vector <int> :: iterator it;
    Viz[nod] = 0;
    Lant[nr].push_back(nod);
    Poz[nod] = Lant[nr].size();
    Place[nod] = nr;
    for (it = G[nod].begin(); it != G[nod].end(); ++it)
        if (Viz[*it])
        {
            if (!Used[nod])
            {
                Used[nod] = 1;
                Lanturi(*it, nr);
            }
            else
            {
                T[++nrp] = nod;
                Lanturi(*it, nrp);
            }
        }
}

void Update(int nod, int st, int dr, int val, int poz, int ind)
{
    if (st == dr)
    {
        while (nod + 1 > Arb[ind].size())
            Arb[ind].push_back(0);
        Arb[ind][nod] = val;
        return;
    }
    int mij = (st + dr) / 2;
    if (poz <= mij)
        Update(2 * nod, st, mij, val, poz, ind);
    else
        Update(2 * nod + 1, mij + 1, dr, val, poz, ind);
    Arb[ind][nod] = max(Arb[ind][2 * nod], Arb[ind][2 * nod + 1]);
}

int Query(int nod, int st, int dr, int left, int right, int ind)
{
    if(left > dr || st > right)
        return -INF;
    if(left <= st && dr <= right)
        return Arb[ind][nod];
    int rez = -INF, mij = (st + dr) / 2;
    rez = max(rez, Query(2 * nod, st, mij, left, right, ind));
    rez = max(rez, Query(2 * nod + 1, mij + 1, dr, left, right, ind));
    return rez;
}

void Operatii()
{
    int op, a, b, sol;
    for (int i = 1; i <= M; ++i)
    {
        scanf("%d %d %d", &op, &a, &b);
        if (op == 0)
            Update(1, 1, Lant[Place[a]].size(), b, Poz[a], Place[a]);
        else
        {
            sol = -1;
            while (Place[a] != Place[b])
            {
                if (H[T[Place[a]]] < H[T[Place[b]]])
                    swap(a, b);
                sol = max(sol, Query(1, 1, Lant[Place[a]].size(), 1, Poz[a], Place[a]));
                a = T[Place[a]];
            }
            if (H[a] < H[b])
                swap(a, b);
            sol = max(sol, Query(1, 1, Lant[Place[a]].size(), H[b] - H[T[Place[a]]], H[a] - H[T[Place[a]]], Place[a]));
            printf("%d\n", sol);
        }
    }
}

int main()
{
    freopen("heavypath.in", "r", stdin);
    freopen("heavypath.out", "w", stdout);

    Citire();
    DFS(1, 1);
    for (int i = 1; i <= N; ++i)
        sort(G[i].begin(), G[i].end(), Comp());
    Lanturi(1, 1);
    for (int i = 1; i <= nrp; ++i)
        for (vector <int> :: iterator it = Lant[i].begin(); it != Lant[i].end(); ++it)
            Update(1, 1, Lant[i].size(), V[*it], Poz[*it], i);
    Operatii();

    return 0;
}