Cod sursa(job #3341564)

Utilizator andrei_nAndrei Nicolae andrei_n Data 19 februarie 2026 23:17:50
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.26 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");

int n, m;
int v[100001];
vector <int> g[100001];
int tata[100001], sz[100001], ad[100001], head[100001], greu[100001], poz[100001], invpoz[100001], timer;

struct arb_int
{
    int aint[400001];

    void build(int node, int l, int r)
    {
        if (l == r)
        {
            aint[node] = v[invpoz[l]];
            return;
        }

        int mid = (l + r) / 2;
        build(2 * node, l, mid);
        build(2 * node + 1, mid + 1, r);

        aint[node] = max(aint[2 * node], aint[2 * node + 1]);
    }

    void update(int node, int poz, int val, int l, int r)
    {
        if (l > poz || r < poz)
            return;
        if (l == r)
        {
            aint[node] = val;
            return;
        }

        int mid = (l + r) / 2;
        update(2 * node, poz, val, l, mid);
        update(2 * node + 1, poz, val, mid + 1, r);

        aint[node] = max(aint[2 * node], aint[2 * node + 1]);
    }

    void update(int poz, int val)
    {
        update(1, poz, val, 1, n);
    }

    int query(int node, int l, int r, int ql, int qr)
    {
        if (r < ql || l > qr)
            return 0;

        if (l >= ql && r <= qr)
            return aint[node];

        int mid = (l + r) / 2;
        return max(query(2 * node, l, mid, ql, qr), query(2 * node + 1, mid + 1, r, ql, qr));
    }

    int query(int l, int r)
    {
        return query(1, 1, n, l, r);
    }
} aint;


void dfs1(int node, int parent)
{
    sz[node] = 1;

    int best = 0;
    for (auto vecin : g[node])
        if (vecin != parent)
        {
            tata[vecin] = node;
            ad[vecin] = ad[node] + 1;
            dfs1(vecin, node);
            sz[node] += sz[vecin];
            if (sz[vecin] > best)
            {
                greu[node] = vecin;
                best = sz[vecin];
            }
        }
}

void dfs2(int node, int h)
{
    head[node] = h;
    poz[node] = ++timer;
    invpoz[timer] = node;

    if (greu[node] != -1)
        dfs2(greu[node], h);

    for (auto vecin : g[node])
        if (vecin != tata[node] && vecin != greu[node])
            dfs2(vecin, vecin);
}

int query_path(int x, int y)
{
    int ans = 0;
    while (head[x] != head[y])
    {
        if (ad[head[x]] < ad[head[y]])
            swap(x, y);
        ans = max(ans, aint.query(poz[head[x]], poz[x]));
        x = tata[head[x]];
    }
    if (ad[x] > ad[y])
        swap(x, y);
    ans = max(ans, aint.query(poz[x], poz[y]));

    return ans;
}

void update_node(int u, long long x)
{
    aint.update(poz[u], x);
}

int main()
{
    fin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        fin >> v[i];
        greu[i] = -1;
    }


    for (int i = 1; i <= n - 1; i++)
    {
        int x, y;
        fin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
    }

    dfs1(1, 0);
    dfs2(1, 1);

    aint.build(1, 1, n);

    for (int i = 1; i <= m; i++)
    {
        int t, x, y;
        fin >> t >> x >> y;
        if (t == 0)
            update_node(x, y);
        else
            fout << query_path(x, y) << '\n';
    }
    return 0;
}