Cod sursa(job #3341412)

Utilizator Victor5539Tanase Victor Victor5539 Data 19 februarie 2026 14:46:57
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.14 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

const int NMAX=1e5;
int n,i,v[NMAX+5],q,s[NMAX+5],parent[NMAX+5],depth[NMAX+5],heavy[NMAX+5],head[NMAX+5],poz[NMAX+5],g[NMAX+5],node1,node2,t;
bool viz[NMAX+5];
vector <int> adj[NMAX+5];

struct SegTree{
    int A[4*NMAX+5],sol;

    void build(int nod, int st, int dr, int v[])
    {
        if (st==dr)
            A[nod]=v[st];
        else
        {
            int mij=(st+dr)>>1;

            build(2*nod,st,mij,v);
            build(2*nod+1,mij+1,dr,v);

            A[nod]=max(A[2*nod],A[2*nod+1]);
        }
    }

    void update(int nod ,int st ,int dr ,int p, int x)
    {
        if (st==dr)
            A[nod]=x;
        else
        {
            int mij=(st+dr)>>1;

            if (p<=mij)
                update(2*nod,st,mij,p,x);
            else
                update(2*nod+1,mij+1,dr,p,x);

            A[nod]=max(A[2*nod],A[2*nod+1]);
        }
    }

    void query(int nod, int st ,int dr ,int a ,int b)
    {
        if (a<=st && dr<=b)
            sol=max(A[nod],sol);
        else
        {
            int mij=(st+dr)>>1;

            if (a<=mij)
                query(2*nod,st,mij,a,b);

            if (b>mij)
                query(2*nod+1,mij+1,dr,a,b);
        }
    }

    int ans(int st, int dr)
    {
        sol=0;
        query(1,1,n,st,dr);
        return sol;
    }
}AINT;

void dfs(int node)
{
    viz[node]=1;
    s[node]=1;
    heavy[node]=-1;

    int sz=0;

    for (auto node2: adj[node])
    {
        if (!viz[node2])
        {
            depth[node2]=depth[node]+1;
            parent[node2]=node;
            dfs(node2);
            s[node]+=s[node2];

            if (sz<s[node2])
            {
                sz=s[node2];
                heavy[node]=node2;
            }
        }
    }
}

void dfs_HLD(int node, int h)
{
    head[node]=h;
    poz[node]= ++t;
    g[poz[node]]=v[node];
    viz[node]=1;

    if (heavy[node]!=-1)
        dfs_HLD(heavy[node],h);

    for (auto node2: adj[node])
        if (!viz[node2])
            dfs_HLD(node2,node2);
}

int query(int a, int b)
{
    int ans=0;

    while (head[a]!=head[b])
    {
        if (depth[head[a]]<depth[head[b]])
            swap(a,b);

        ans=max(ans,AINT.ans(poz[head[a]],poz[a]));
        a=parent[head[a]];
    }

    if (depth[a]>depth[b])
        swap(a,b);

    ans=max(ans,AINT.ans(poz[a],poz[b]));

    return ans;
}


int main()
{
    ios_base::sync_with_stdio(false);
    fin.tie(nullptr); fout.tie(nullptr);

    fin>>n>>q;
    for (i=1; i<=n; i++)
        fin>>v[i];

    for (i=1; i<n; i++)
    {
        fin>>node1>>node2;
        adj[node1].push_back(node2);
        adj[node2].push_back(node1);
    }

    dfs(1);

    for (i=1; i<=n; i++)
        viz[i]=0;

    dfs_HLD(1,1);

    AINT.build(1,1,n,g);

    while(q--)
    {
        int x,y;
        fin>>t>>x>>y;
        if (t==0)
            AINT.update(1,1,n,poz[x],y);
        else
            fout<<query(x,y)<<'\n';
    }

    return 0;
}