Cod sursa(job #3307523)

Utilizator davidgeo123Georgescu David davidgeo123 Data 21 august 2025 14:20:38
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.4 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX=1e5;
int n, q, val[NMAX+1];
vector<int> g[NMAX+1];
int depth[NMAX+1], sz[NMAX+1], par[NMAX+1], heavy[NMAX+1], head[NMAX+1], pos[NMAX+1];

int t[4*NMAX+4];
void segment_update(int v, int tl, int tr, int pos, int val)
{
    if(tl==tr)
    {
        t[v]=val;
        return;
    }

    int tm=(tl+tr)>>1;
    if(pos<=tm)segment_update(2*v, tl, tm, pos, val);
    else segment_update(2*v+1, tm+1, tr, pos, val);
    t[v]=max(t[2*v], t[2*v+1]);
}

int segment_query(int v, int tl, int tr, int l, int r)
{
    if(l>r)return 0;
    if(tl==l && tr==r)return t[v];

    int tm=(tl+tr)>>1;
    return max(segment_query(2*v, tl, tm, l, min(r, tm)),
                segment_query(2*v+1, tm+1, tr, max(l, tm+1), r));
}
void dfs(int nod, int p)
{
    depth[nod]=depth[p]+1;
    par[nod]=p;
    sz[nod]=1;
    int max_s=0;
    for(auto &copil:g[nod])
        if(copil!=p)
        {
            dfs(copil, nod);
            sz[nod]+=sz[copil];
            if(sz[copil]>max_s)
                max_s=sz[copil], heavy[nod]=copil;
        }
}

int tt;
void decompose(int nod, int h)
{
    head[nod]=h;
    pos[nod]=(++tt);
    segment_update(1, 1, n, pos[nod], val[nod]);
    if(heavy[nod])
        decompose(heavy[nod], h);

    for(auto &copil:g[nod])
        if(copil!=par[nod] && copil!=heavy[nod])
            decompose(copil, copil);
}

int query(int a, int b)
{
    int maxim=0;
    for(; head[a]!=head[b]; b=par[head[b]])
    {
        if(depth[head[a]] > depth[head[b]])swap(a, b);
        maxim=max(maxim, segment_query(1, 1, n, pos[head[b]], pos[b]));
    }
    if(depth[a] > depth[b])swap(a, b);
    maxim=max(maxim, segment_query(1, 1, n, pos[a], pos[b]));
    return maxim;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    freopen("heavypath.in", "r", stdin);
    freopen("heavypath.out", "w", stdout);
    cin>>n>>q;
    for(int i=1; i<=n; i++)
        cin>>val[i];
    for(int i=1, x, y; i<n; i++)
    {
        cin>>x>>y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    dfs(1, 0);
    decompose(1, 1);
    while(q--)
    {
        int tip, x, y;
        cin>>tip>>x>>y;
        if(tip==0)
        {
            segment_update(1, 1, n, pos[x], y);
        }
        else
        {
            cout<<query(x, y)<<'\n';
        }
    }
    return 0;
}