Cod sursa(job #3348970)

Utilizator robertcosacCosac Robert-Mihai robertcosac Data 24 martie 2026 21:21:54
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.76 kb
#include <bits/stdc++.h>
#define int long long
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
vector <int> v[100009];
int tata[100009], lin[100009], poz[100009], head[100009], aint[400009], dim[100009], nivel[100009], n, cnt=0, val[100009];
void update (int nod, int st, int dr, int poz, int val)
{
    if (st==dr)
        aint[nod]=val;
    else
    {
        int mij=(st+dr)/2;
        if (poz<=mij)
            update (2*nod, st, mij, poz, val);
        else
            update (2*nod+1, mij+1, dr, poz, val);
        aint[nod]=max (aint[2*nod], aint[2*nod+1]);
    }
}
void update (int poz, int val)
{
    update (1, 1, n, poz, val);
}
int query (int nod, int st, int dr, int l, int r)
{
    if (st==l && dr==r)
        return aint[nod];
    int mij=(st+dr)/2;
    if (mij>=r)
        return query (2*nod, st, mij, l, r);
    else if (mij<l)
        return query (2*nod+1, mij+1, dr, l, r);
    else
        return max (query (2*nod, st, mij, l, mij), query (2*nod+1, mij+1, dr, mij+1, r));
}
int query (int l, int r)
{
    return query (1, 1, n, l, r);
}
void dfs (int nod, int t)
{
    dim[nod]=1;
    tata[nod]=t;
    for (auto y:v[nod])
    {
        if (y!=t)
        {
            nivel[y]=nivel[nod]+1;
            dfs (y, nod);
            dim[nod]+=dim[y];
        }
    }
}
void dfs_greu (int nod)
{
    lin[++cnt]=nod;
    poz[nod]=cnt;
    int greu=0;
    for (auto y:v[nod])
    {
        if (y!=tata[nod] && dim[y]>dim[greu])
            greu=y;
    }
    if (greu)
    {
        head[greu]=head[nod];
        dfs_greu (greu);
    }
    for (auto y:v[nod])
        if (y!=greu && y!=tata[nod])
        dfs_greu (y);
}
int query_greu (int x, int y)
{
    int sol=0;
    if (head[x]==head[y])
    {
        if (poz[x]<poz[y])
            sol=query (poz[x], poz[y]);
        else
            sol=query (poz[y], poz[x]);
    }
    else
    {
        if (nivel[head[x]]<nivel[head[y]])
            swap (x, y);
        sol=max (sol, query(poz[head[x]], poz[x]));
        x=head[x];
        x=tata[x];
        sol=max (sol, query_greu(x,y));
    }
    return sol;
}
signed main ()
{
    int q;
    f >> n >> q;
    for (int i=1; i<=n; i++)
        f >> val[i];
    for (int i=1; i<n; i++)
    {
        int x, y;
        f >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs (1, 0);
    for (int i=1; i<=n; i++)
        head[i]=i;
    dfs_greu (1);
    //cout <<"*";
    for (int i=1; i<=n; i++)
        update (i, val[i]);
    //cout <<"*";
    while (q--)
    {
        int tip, a, b;
        f >> tip >> a >> b;
        if (!tip)
            update (poz[a], b);
        else
            g << query_greu (a, b) << '\n';
    }
}