Cod sursa(job #3137412)

Utilizator lucriLuchian Cristian lucri Data 12 iunie 2023 19:56:25
Problema Heavy Path Decomposition Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.92 kb
#include <bits/stdc++.h>
std::ifstream cin("heavypath.in");
std::ofstream cout("heavypath.out");
int rid[100010],ta[100010],n,m,nrpoz=-1,v[100010],bhld[100010],poz[100010],nrf[100010],ehld[100010],id[100010],nrid,x,y,z;
std::vector<std::vector<int>>a;
int aint[400010];
void adancimemax(int nod,int t)
{
    for(auto x:a[nod])
    {
        if(x==t)
            continue;
        adancimemax(x,nod);
        nrf[nod]=std::max(nrf[x],nrf[nod]);
    }
    nrf[nod]++;
}
void creazaaint(int poz,int b,int e)
{
    nrpoz=std::max(nrpoz,poz);
    if(b==e)
        return;
    creazaaint(poz*2,b,(b+e)/2);
    creazaaint(poz*2+1,(b+e)/2+1,e);
}
void create(int nod,int t,int b)
{
    ta[nod]=t;
    int hc=0;
    id[nod]=++nrid;
    rid[nrid]=nod;
    bhld[id[nod]]=b;
    for(auto x:a[nod])
    {
        if(x==t)
            continue;
        if(nrf[x]>nrf[hc])
            hc=x;
    }
    if(hc)
    {
        create(hc,nod,b);
        ehld[id[nod]]=ehld[id[hc]];
    }
    else
    {
        ehld[id[nod]]=nrid;
    }
    if(id[nod]==bhld[id[nod]])
    {
        nrpoz+=2;
        poz[bhld[id[nod]]]=nrpoz;
        creazaaint(nrpoz,bhld[id[nod]],ehld[id[nod]]);
    }
    for(auto x:a[nod])
    {
        if(x==t||x==hc)
            continue;
        create(x,nod,nrid+1);
    }
}
void update(int poz,int b,int e,int pozu,int val)
{
    if(e<pozu||pozu<b)
        return;
    if(b==e)
    {
        aint[poz]=val;
        return;
    }
    update(poz*2,b,(b+e)/2,pozu,val);
    update(poz*2+1,(b+e)/2+1,e,pozu,val);
    aint[poz]=std::max(aint[poz*2],aint[poz*2+1]);
    return;
}
int raspunde(int poz,int b,int e,int bi,int ei)
{
    if(e<bi||ei<b)
        return 0;
    if(bi<=b&&e<=ei)
        return aint[poz];
    int x=raspunde(poz*2,b,(b+e)/2,bi,ei);
    int y=raspunde(poz*2+1,(b+e)/2+1,e,bi,ei);
    return std::max(x,y);
}
int main()
{
    cin>>n>>m;
    a.resize(n+5);
    for(int i=1;i<=n;++i)
    {
        cin>>v[i];
    }
    for(int i=1;i<n;++i)
    {
        cin>>x>>y;
        a[x].push_back(y);
        a[y].push_back(x);
    }
    adancimemax(1,-1);
    create(1,-1,1);
    for(int i=1;i<=n;++i)
    {
        update(poz[bhld[id[i]]],bhld[id[i]],ehld[id[i]],id[i],v[i]);
    }
    while(m--)
    {
        cin>>z>>x>>y;
        if(z==0)
            update(poz[bhld[id[x]]],bhld[id[x]],ehld[id[x]],id[x],y);
        else
        {
            int ans=0;
            while(bhld[id[x]]!=bhld[id[y]])
            {
                if(id[y]>id[x])
                    x^=y^=x^=y;
                ans=std::max(ans,raspunde(poz[bhld[id[x]]],bhld[id[x]],ehld[id[x]],bhld[id[x]],id[x]));
                x=ta[rid[bhld[id[x]]]];
            }
            if(id[y]>id[x])
                x^=y^=x^=y;
            ans=std::max(ans,raspunde(poz[bhld[id[x]]],bhld[id[x]],ehld[id[x]],id[y],id[x]));
            cout<<ans<<'\n';
        }
    }
    return 0;
}