Cod sursa(job #3040887)

Utilizator IvanAndreiIvan Andrei IvanAndrei Data 30 martie 2023 16:05:13
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.19 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int max_size = 1e5 + 1, max_aint = 4e5 + 1;

vector <int> mc[max_size];
int val[max_size], v[max_size], t[max_size], cap[max_size], aint[max_aint], depth[max_size], sz[max_size], ind[max_size], timp, n;

void dfs (int nod, int par)
{
    t[nod] = par;
    depth[nod] = depth[par] + 1;
    sz[nod] = 1;
    cap[nod] = nod;
    for (auto f : mc[nod])
    {
        if (f == par)
        {
            continue;
        }
        dfs(f, nod);
        sz[nod] += sz[f];
    }
}

void dfsh (int nod, int par)
{
    ++timp;
    ind[nod] = timp;
    int mx = -1, urm;
    for (auto f : mc[nod])
    {
        if (f == par)
        {
            continue;
        }
        if (sz[f] > mx)
        {
            mx = sz[f];
            urm = f;
        }
    }
    if (mx == -1)
    {
        return;
    }
    cap[urm] = cap[nod];
    dfsh(urm, nod);
    for (auto f : mc[nod])
    {
        if (f == par || f == urm)
        {
            continue;
        }
        dfsh(f, nod);
    }
}

void init (int l, int r, int nod)
{
    if (l == r)
    {
        aint[nod] = v[l];
        return;
    }
    int m = (l + r) / 2;
    init(l, m, 2 * nod);
    init(m + 1, r, 2 * nod + 1);
    aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
}

void upd (int l, int r, int poz, int val, int nod)
{
    if (l == r)
    {
        aint[nod] = val;
        return;
    }
    int m = (l + r) / 2;
    if (poz <= m)
    {
        upd(l, m, poz, val, 2 * nod);
    }
    else
    {
        upd(m + 1, r, poz, val, 2 * nod + 1);
    }
    aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
}

int queryaint (int l, int r, int st, int dr, int nod)
{
    if (st <= l && r <= dr)
    {
        return aint[nod];
    }
    int m = (l + r) / 2, mx1 = 0, mx2 = 0;
    if (st <= m)
    {
        mx1 = queryaint(l, m, st, dr, 2 * nod);
    }
    if (dr > m)
    {
        mx2 = queryaint(m + 1, r, st, dr, 2 * nod + 1);
    }
    return max(mx1, mx2);
}

int queryheavy (int x, int y)
{
    if (cap[x] == cap[y])
    {
        if (ind[x] > ind[y])
        {
            swap(x, y);
        }
        return queryaint(1, n, ind[x], ind[y], 1);
    }
    if (depth[cap[x]] < depth[cap[y]])
    {
        swap(x, y);
    }
    return max(queryaint(1, n, ind[cap[x]], ind[x], 1), queryheavy(t[cap[x]], y));
}

int main ()
{
    int q;
    in >> n >> q;
    for (int i = 1; i <= n; i++)
    {
        in >> val[i];
    }
    for (int i = 1; i < n; i++)
    {
        int x, y;
        in >> x >> y;
        mc[x].push_back(y);
        mc[y].push_back(x);
    }
    dfs(1, 0);
    dfsh(1, 0);
    for (int i = 1; i <= n; i++)
    {
        //out << ind[i] << " ";
        v[ind[i]] = val[i];
    }
    init(1, n, 1);
    while (q--)
    {
        int op, x, y;
        in >> op >> x >> y;
        if (op == 0)
        {
            upd(1, n, ind[x], y, 1);
        }
        else
        {
            out << queryheavy(x, y) << '\n';
        }
    }
    in.close();
    out.close();
    return 0;
}