Cod sursa(job #3348961)

Utilizator Carnu_EmilianCarnu Emilian Carnu_Emilian Data 24 martie 2026 20:36:12
Problema Heavy Path Decomposition Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.95 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
typedef long long ll;

#define int ll

const int N = 1e5 + 5;
int n, q, a, b, g[N], sz[N], nrp[N], k, *aint[N], poz[N], lvl[N], minlvl[N], parent[N];
bool viz[N];
vector<int> v[N], path[N];

void DFS(int nod, int niv)
{
    sz[nod] = 1;
    lvl[nod] = niv;
    viz[nod] = true;
    int maxsz, heavyson;
    maxsz = 0;
    heavyson = -1;
    for (int i : v[nod])
        if (!viz[i])
        {
            DFS(i, niv + 1);
            sz[nod] += sz[i];
            if (sz[i] > maxsz)
            {
                maxsz = sz[i];
                heavyson = i;
            }
        }
        else
            parent[nod] = i;
    if (heavyson == -1)
        nrp[nod] = ++k;
    else
        nrp[nod] = nrp[heavyson];
    path[nrp[nod]].push_back(nod);
}

void Update(int i, int nod, int st, int dr, int poz, int val)
{
    int m = (st + dr) / 2;
    if (st == dr)
        aint[i][nod] = val;
    else
    {
        if (poz <= m)
            Update(i, 2 * nod, st, m, poz, val);
        else
            Update(i, 2 * nod + 1, m + 1, dr, poz, val);
        aint[i][nod] = max(aint[i][2 * nod], aint[i][2 * nod + 1]);
    }
}

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

void hld()
{
    for (int i = 1; i <= k; i++)
    {
        aint[i] = new int[2 * path[i].size() + 5];
        minlvl[i] = lvl[path[i].back()];
        for (int j = 0; j < path[i].size(); j++)
        {
            poz[path[i][j]] = j;
            Update(i, 1, 1, path[i].size(), j + 1, g[path[i][j]]);
        }
    }
}

int descomp(int a, int b)
{
    int rasp = 0;
    while (nrp[a] != nrp[b])
    {
        if (minlvl[nrp[a]] < minlvl[nrp[b]])
            swap(a, b);
        /// a este mai jos
        //cout << a << ' ' << b << '\n';
        rasp = max(rasp, Query(nrp[a], 1, 1, path[nrp[a]].size(), poz[a] + 1, path[nrp[a]].size()));
        a = parent[path[nrp[a]].back()];
    }
    if (poz[a] > poz[b])
        swap(a, b);
    //cout << a << ' ' << b << '\n';
    rasp = max(rasp, Query(nrp[a], 1, 1, path[nrp[a]].size(), poz[a] + 1, poz[b] + 1));
    return rasp;
}

signed main()
{
    fin >> n >> q;
    for (int i = 1; i <= n; i++)
        fin >> g[i];
    for (int i = 1; i < n; i++)
    {
        fin >> a >> b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    DFS(1, 0);
    hld();
    for (int i = 1; i <= q; i++)
    {
        int op, x, y;
        fin >> op >> x >> y;
        if (op == 0)
        {
            Update(nrp[x], 1, 1, path[nrp[x]].size(), poz[x] + 1, y);
        }
        if (op == 1)
        {
            int rasp;
            rasp = descomp(x, y);
            fout << rasp << '\n';
        }
    }
}