Cod sursa(job #3286540)

Utilizator _andrei4567Stan Andrei _andrei4567 Data 14 martie 2025 12:43:55
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.44 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int N = 1e5;
int v[N + 1], sub[N + 1], heavy_son[N + 1], t[N + 1], inv_time[N + 1], dad_lant[N + 1], dad[N + 1], lantul[N + 1], dist[N + 1];

vector <int> g[N + 1];

int n, m, cer, x, y, timp, lant;

void dfs (int node, int tata)
{
    sub[node] = 1;
    dist[node] = dist[tata] + 1;
    dad[node] = tata;
    for (auto it : g[node])
        if (it != tata)
        {
            dfs (it, node);
            sub[node] += sub[it];
            if (sub[heavy_son[node]] < sub[it])
                heavy_son[node] = it;
        }
}

void dfs_first (int node, int tata)
{
    ++timp;
    t[node] = timp;
    inv_time[timp] = node;
    if (heavy_son[tata] != node)
    {
        ++lant;
        lantul[node] = lant;
        dad_lant[lant] = node;
    }
    else
        lantul[node] = lant;
    if (heavy_son[node])
        dfs_first(heavy_son[node], node);
    for (auto it : g[node])
        if (it != tata && it != heavy_son[node])
            dfs_first (it, node);
}

struct aint
{
    int arb[4 * N + 1];
    aint ()
    {
        for (int i = 1; i <= 4 * N; ++i)
            arb[i] = 0;
    }
    void build (int node, int l, int r)
    {
        if (l == r)
        {
            arb[node] = v[inv_time[l]];
            return;
        }
        int med = (l + r) >> 1;
        build (node << 1, l, med);
        build (node << 1 | 1, med + 1, r);
        arb[node] = max (arb[node << 1], arb[node << 1 | 1]);
    }
    void update (int node, int l, int r, int poz, int val)
    {
        if (l == r)
        {
            arb[node] = val;
            return;
        }
        int med = (l + r) >> 1;
        if (poz <= med)update (node << 1, l, med, poz, val);
        else update (node << 1 | 1, med + 1, r, poz, val);
        arb[node] = max (arb[node << 1], arb[node << 1 | 1]);
    }
    int query (int node, int l, int r, int st, int dr)
    {
        if (l >= st && r <= dr)
            return arb[node];
        int med = (l + r) >> 1;
        int rez1, rez2;
        rez1 = rez2 = 0;
        if (st <= med) rez1 = query (node << 1, l, med, st, dr);
        if (dr > med) rez2 = query (node << 1 | 1, med + 1, r, st, dr);
        return max (rez1, rez2);
    }
} l;

int query (int x, int y)
{
    int ans = 0;
    while (lantul[x] != lantul[y])
    {
        int dadx = dad_lant[lantul[x]];
        int dady = dad_lant[lantul[y]];
        if (dist[dadx] < dist[dady])
        {
            ans = max (ans, l.query(1, 1, n, t[dady], t[y]));
            y = dad[dady];
        }
        else
        {
            ans = max (ans, l.query(1, 1, n, t[dadx], t[x]));
            x = dad[dadx];
        }
    }
    ans = max (ans, l.query(1, 1, n, min (t[x], t[y]), max(t[x], t[y])));
    return ans;
}

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
        cin >> v[i];
    for (int i = 1; i < n; ++i)
    {
        cin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    dfs (1, 0);
    dfs_first(1, 0);
    l.build(1, 1, n);
    for (int i = 1; i <= m; ++i)
    {
        cin >> cer >> x >> y;
        if (!cer)
        {
            l.update (1, 1, n, t[x], y);
            v[x] = y;
        }
        else
        {
            cout << query (x, y) << '\n';
        }
    }
    return 0;
}