Cod sursa(job #3325732)

Utilizator Anul2024Anul2024 Anul2024 Data 26 noiembrie 2025 11:05:59
Problema Heavy Path Decomposition Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.96 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");
const int DIM = 100000, DIMP = 262144;
int n, q, k;
int nodes[DIM + 1], vali[DIM + 1], heavy_head[DIM + 1], heavy_vec[DIM + 1];
int cnt[DIM + 1], niv[DIM + 1], t[DIM + 1], pos[DIM + 1];
vector <int> v[DIM + 1];
struct AINT
{
    int v[DIMP + 1];
    int pos, val;
    int posl, posr, sol;
    void build (int nod, int l, int r)
    {
        if (l == r)
            v[nod] = vali[nodes[l]];
        else
        {
            int mid = (l + r) / 2;
            build (2 * nod, l, mid);
            build (2 * nod + 1, mid + 1, r);
            v[nod] = max (v[2 * nod], v[2 * nod + 1]);
        }
    }
    void update (int nod, int l, int r)
    {
        if (l == r)
            v[nod] = val;
        else
        {
            int mid = (l + r) / 2;
            if (pos <= mid)
                update (2 * nod, l, mid);
            if (pos > mid)
                update (2 * nod + 1, mid + 1, r);
            v[nod] = max (v[2 * nod], v[2 * nod + 1]);
        }
    }
    void query (int nod, int l, int r)
    {
        if (l >= posl && r <= posr)
            sol = max (sol, v[nod]);
        else
        {
            int mid = (l + r) / 2;
            if (posl <= mid)
                query (2 * nod, l, mid);
            if (posr > mid)
                query (2 * nod + 1, mid + 1, r);
        }
    }
    void prep_update (int pos, int val)
    {
        this -> pos = pos;
        this -> val = val;
        update (1, 1, n);
    }
    int prep_query (int posl, int posr)
    {
        this -> posl = posl;
        this -> posr = posr;
        this -> sol = 0;
        query (1, 1, n);
        return sol;
    }
};
AINT aint;
void read ()
{
    int x, y;
    fin >> n >> q;
    for (int i = 1; i <= n; i++)
        fin >> vali[i];
    for (int i = 1; i < n; i++)
    {
        fin >> x >> y;
        v[x].push_back (y);
        v[y].push_back (x);
    }
}
void dfs1 (int nod, int tt, int p)
{
    niv[nod] = p;
    t[nod] = tt;
    cnt[nod] = 1;
    for (int i = 0; i < (int) v[nod].size (); i++)
    {
        int vecin = v[nod][i];
        if (vecin != tt)
        {
            dfs1 (vecin, nod, p + 1);
            if (cnt[vecin] > cnt[heavy_vec[nod]])
                heavy_vec[nod] = vecin;
            cnt[vecin] += cnt[nod];
        }
        else
        {
            v[nod][i] = v[nod].back ();
            v[nod].pop_back ();
            i--;
        }
    }
}
void dfs2 (int nod)
{
    k++;
    pos[nod] = k;
    nodes[k] = nod;
    if (heavy_vec[nod])
    {
        heavy_head[heavy_vec[nod]] = heavy_head[nod];
        dfs2 (heavy_vec[nod]);
    }
    for (int i = 0; i < (int) v[nod].size (); i++)
    {
        int vecin = v[nod][i];
        if (vecin != heavy_vec[nod])
        {
            heavy_head[vecin] = vecin;
            dfs2 (vecin);
        }
    }
}
int solve (int x, int y)
{
    int sol = 0;
    while (heavy_head[x] != heavy_head[y])
    {
        if (niv[heavy_head[x]] > niv[heavy_head[y]])
        {
            sol = max (sol, aint.prep_query (pos[heavy_head[x]], pos[x]));
            x = t[heavy_head[x]];
        }
        else
        {
            sol = max (sol, aint.prep_query (pos[heavy_head[y]], pos[y]));
            y = t[heavy_head[y]];
        }
    }
    if (pos[x] <= pos[y])
        sol = max (sol, aint.prep_query (pos[x], pos[y]));
    else
        sol = max (sol, aint.prep_query (pos[y], pos[x]));
    return sol;
}
void solve_qry ()
{
    int ch, x, y;
    while (q--)
    {
        fin >> ch >> x >> y;
        if (ch == 0)
            aint.prep_update (pos[x], y);
        else
            fout << solve (x, y) << "\n";
    }
}
int main ()
{
    read ();
    dfs1 (1, 0, 1);
    heavy_head[1] = 1;
    dfs2 (1);
    aint.build (1, 1, n);
    solve_qry ();
    return 0;
}