Cod sursa(job #3334959)

Utilizator robertcosacCosac Robert-Mihai robertcosac Data 20 ianuarie 2026 20:07:22
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.86 kb
#include <bits/stdc++.h>
#define int long long
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int aint[400009], n, val[100009], poz[100009], nivel[100009], dim[100009], head[100009], q, lin[100009], cnt=0, tata[100009];
vector <int> v[100009];
int query (int nod, int st, int dr, int left, int right)
{
    if (left>right)
        swap (left, right);
    if (st==left && dr==right)
        return aint[nod];
    int mij=(st+dr)/2;
    if (right<=mij)
        return query (2*nod, st, mij, left, right);
    if (left>mij)
        return query (2*nod+1, mij+1, dr, left, right);
    else
        return max (query(2*nod, st, mij, left, mij), query(2*nod+1, mij+1, dr, mij+1, right));
}
int query (int st, int dr)
{
    return query (1, 1, n, st, dr);
}
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);
}
void dfs (int nod, int tata1)
{
    dim[nod]++;
    tata[nod]=tata1;
    for (auto y:v[nod])
    {
        if (y!=tata1)
        {
            nivel[y]=nivel[nod]+1;
            dfs (y, nod);
            dim[nod]+=dim[y];
        }
    }
}
void dfs_greu (int nod, int tata1)
{
    lin[++cnt]=nod;
    poz[nod]=cnt;
    int heavy=0;
    for (auto y:v[nod])
    {
        if (y!=tata1 && dim[y]>dim[heavy])
            heavy=y;
    }
    if (!heavy)
        return;
    head[heavy]=head[nod];
    dfs_greu (heavy, nod);
    for (auto y:v[nod])
    {
        if (y!=tata1 && y!=heavy)
            dfs_greu (y, nod);
    }
}
int query_greu (int x, int y)
{
    //cout << x << ' ' << y << '\n';
    int sol=0;
    if (head[x]==head[y])
        sol=query (poz[x], poz[y]);
    else
    {
        int t1=head[x], t2=head[y];
        if (nivel[t1]>nivel[t2])
            sol=query (poz[x], poz[t1]), x=tata[t1];
        else
            sol=query (poz[y], poz[t2]), y=tata[t2];
        sol=max (sol, query_greu(x, y));
    }
    return sol;


}
signed main ()
{
    f >>n >> q;
    for (int i=1; i<=n; i++)
        f >> val[i], head[i]=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);
    dfs_greu (1, 0);
    for (int i=1; i<=n; i++)
        update (i, val[i]);
    //cout << head[3] << ' ';
    while (q--)
    {
        //cout << '*';
        int tip;
        f >> tip;
        int x, y;
        f >> x >> y;
        if (!tip)
            update (poz[x], y);
        else
            g << query_greu (x, y) << '\n';
    }
}