Cod sursa(job #3342397)

Utilizator andrei1232008nicolae andrei andrei1232008 Data 24 februarie 2026 00:44:32
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
const int lim=1e5+10;
int n,Q,i,x[lim],t[lim],d[lim],aint[4*lim],vf,timer,task;
int head[lim],heavy[lim],sz[lim],val[lim],pos[lim];
vector <int> v[lim];
void dfs(int k,int origin)
{
    sz[k]=1;
    heavy[k]=0;

    int mx=0;
    for(auto x:v[k])
    {
        if(x==origin)continue;
        d[x]=d[k]+1;
        dfs(x,k);

        sz[k]+=sz[x];
        if(sz[x]>mx)
        {
            mx=sz[x];
            heavy[k]=x;
        }
    }
}
void decompose(int k,int h)
{
    head[k]=h;
    pos[k]=++timer;
    val[timer]=x[k];

    if(heavy[k])
        decompose(heavy[k],h);

    for(auto x:v[k])
    {
        if(x==t[k]||x==heavy[k])continue;
        decompose(x,x);
    }
}
void update(int pos,int x)
{
    pos+=timer;
    pos--;
    aint[pos]=x;
    pos/=2;
    while(pos)
    {
        aint[pos]=max(aint[2*pos],aint[2*pos+1]);
        pos/=2;
    }
}
int query(int l,int r)
{
    l--;r--;
    l+=timer;r+=timer;
    int ans=-1e9;
    while(l<=r)
    {
        if(l%2)ans=max(ans,aint[l]);
        if(!(r%2))ans=max(ans,aint[r]);
        l=(l+1)/2;
        r=(r-1)/2;
    }
    return ans;
}
int query_path(int x,int y)
{
    int ans=0;
    while(head[x]!=head[y])
    {
        if(d[head[x]]<d[head[y]])swap(x,y);
        ans=max(ans,query(pos[head[x]],pos[x]));
        x=t[head[x]];
    }
    if(d[x]>d[y])
        swap(x,y);
    ans=max(ans,query(pos[x],pos[y]));
    return ans;
}
int main()
{
    fin>>n>>Q;
    for(i=1;i<=n;i++)
        fin>>x[i];
    for(i=1;i<=n-1;i++)
    {
        int x,y;
        fin>>x>>y;
        t[y]=x;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for(i=1;i<=n;i++)
        if(t[i]==0){vf=i;break;}
    dfs(vf,vf);

    decompose(vf,vf);

    for(i=1;i<=timer;i++)
        aint[i+timer-1]=val[i];
    for(i=timer-1;i>0;i--)
        aint[i]=max(aint[2*i],aint[2*i+1]);

    while(Q--)
    {
        fin>>task;
        if(task==0)
        {
            int x,y;
            fin>>x>>y;
            update(pos[x],y);
        }
        else
        {
            int x,y;
            fin>>x>>y;
            fout<<query_path(x,y)<<'\n';
        }
    }
    return 0;
}