Cod sursa(job #3289519)

Utilizator Darius1414Dobre Darius Adrian Darius1414 Data 27 martie 2025 11:48:33
Problema Heavy Path Decomposition Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.86 kb
#include <bits/stdc++.h>
#define nmx 100005
using namespace std;
int n,val[nmx],m,a,b,rsp,ord[nmx],ct,sef[nmx],jos[nmx],nr[nmx],arb[4*nmx],where[nmx],up[17][nmx];
int niv[nmx];
vector <int> v[nmx];
void dfs(int source,int father)
{
    niv[source]=niv[father]+1;
    up[0][source]=father;
    int ok=0,mx=0,ctm=0,which;
    for (auto it : v[source])
        if (it!=father)
        {
            dfs(it,source);
            ok=1;
            if (nr[it]>mx)
            {
                mx=nr[it];
                ctm++;
                which=it;
            }
            else if (nr[it]==mx)
                ctm++;
        }
    if (!ok)
    {
        sef[source]=source;
        jos[source]=source;
        nr[source]=1;
        return;
        ///frunza
    }
    if (ctm>=2)
        mx++;
    sef[jos[which]]=source;
    jos[source]=jos[which];
    nr[source]=mx;
}
void build (int st,int dr,int index)
{
    if (st==dr)
    {
        arb[index]=val[ord[st]];
        return;
    }
    int mid=(st+dr)/2;
    build(st,mid,index*2);
    build(mid+1,dr,index*2+1);
    arb[index]=max(arb[index*2],arb[index*2+1]);
}
void update(int st,int dr,int index)
{
    if (st==dr)
    {
        arb[index]=b;
        return;
    }
    int mid=(st+dr)/2;
    if (a<=mid)
        update(st,mid,index*2);
    else update(mid+1,dr,index*2+1);
    arb[index]=max(arb[index*2],arb[index*2+1]);
}
int query(int st,int dr,int a,int b,int index)
{
    if (b<st || dr<a)
        return 0;
    if (a<=st && dr<=b)
        return arb[index];
    int mid=(st+dr)/2;
    return max(query(st,mid,a,b,index*2),query(mid+1,dr,a,b,index*2+1));
}
void doit(int x,int boss)
{
    while (sef[jos[x]]!=sef[jos[boss]])
    {
        int r=query(1,n,where[x],where[sef[jos[x]]],1);
        rsp=max(rsp,r);
        x=up[0][sef[jos[x]]];
    }
    int r=query(1,n,where[x],where[boss],1);
    rsp=max(rsp,r);
}
int main()
{
    ifstream f ("heavypath.in");
    ofstream g ("heavypath.out");
    f>>n>>m;
    for (int i=1; i<=n; i++)
        f>>val[i];
    for (int i=1; i<n; i++)
    {
        f>>a>>b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    dfs(1,0);
    for (int i=1; i<=n; i++)
    {
        if (jos[i]==i)
        {
            int j=i;
            ++ct;
            ord[ct]=j;
            where[j]=ct;
            while (up[0][j]!=up[0][sef[i]])
            {
                j=up[0][j];
                ord[++ct]=j;
                where[j]=ct;
            }
        }
        v[i].clear();
    }
    build(1,n,1);
    int p2=0,p=1;
    while (p*2<=n)
        p*=2,p2++;
    for (int j=1; j<=p2; j++)
        for (int i=1; i<=n; i++)
            up[j][i]=up[j-1][up[j-1][i]];
    int c;
    while (m--)
    {
        f>>c>>a>>b;
        if (c==0)
        {
            val[a]=b;
            a=where[a];
            update(1,n,1);
        }
        else
        {
            if (niv[a]>niv[b])
                swap(a,b);
            int b2=b,a2=a,lca=0;
            int dif=niv[b]-niv[a];
            ///b mai jos
            for (int i=p2; i>=0; i--)
            {
                if ((1<<i)<=dif)
                {
                    dif-=(1<<i);
                    b2=up[i][b2];
                }
            }
            if (a2!=b2)
                for (int i=p2; i>=0; i--)
                {
                    if (up[i][a2]!=up[i][b2])
                    {
                        a2=up[i][a2];
                        b2=up[i][b2];
                    }
                    else lca=up[i][a2];
                }
            else lca=a2;
            if (!lca) lca=a2;
            rsp=0;
            if (lca!=a) doit(a,lca);
            else rsp=val[a];
            if (lca!=b) doit(b,lca);
            else rsp=max(rsp,val[b]);
            g<<rsp<<'\n';
        }
    }
}