Cod sursa(job #3347079)

Utilizator Sorin_GabrielGabara Sorin Gabriel Sorin_Gabriel Data 15 martie 2026 15:46:07
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.94 kb
#include <bits/stdc++.h>
#define INF 1e8+1
#define VMAX 100005
//#define int long long int
using namespace std;

ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");
int n;
int top[VMAX];
int sz[VMAX];
int tin[VMAX];
int heavy[VMAX];
vector<int> graf[VMAX];
int timer=0;
int rmq[(int)log2(VMAX)+10][VMAX];
vector<int> euler_tour_lca;
int timp_euler[VMAX];
int depth[VMAX];
int tata[VMAX];

void decomp(int nod, int crt_top)
{
    tin[nod]=++timer;
    top[nod]=crt_top;

    if(heavy[nod])
    {
        decomp(heavy[nod],nod); // cobor in fiul heavy
    }
    for(auto it:graf[nod])
    {
        if(tin[it])
            continue;
        decomp(it,it); // it devine noul top
    }
}


void dfs(int nod, int parinte)
{
    tata[nod]=parinte;
    sz[nod]=1;
    int maxim=0;

    for(auto it:graf[nod])
    {
        if(it==parinte)
            continue;

        dfs(it,nod);
        if(sz[it]>sz[maxim])
            maxim=it;
        sz[nod]+=sz[it];
    }

    heavy[nod]=maxim;
}


void euler_lca_(int nod,int parinte)
{
    timp_euler[nod]=euler_tour_lca.size();
    euler_tour_lca.push_back(nod);
    for(auto it:graf[nod])
    {
        if(it==parinte)
            continue;
        depth[it]=depth[nod]+1;
        euler_lca_(it,nod);
        euler_tour_lca.push_back(nod);

    }
}

int aint[4*VMAX];
int val_init[VMAX];

void update(int st, int dr, int poz, int nr, int val)
{
    if(st==dr)
    {
        aint[nr]=val;
        return;
    }

    int mij = (st+dr)/2;

    if(poz<=mij)
        update(st,mij,poz,2*nr,val);
    else
        update(mij+1,dr,poz,2*nr+1,val);

    aint[nr]=max(aint[2*nr],aint[2*nr+1]);

}


int query(int st, int dr, int st_interv, int dr_interv, int nr)
{
    if(st_interv<=st && dr<=dr_interv)
        return aint[nr];

    int mij = (st+dr)/2,maxim=-INF;

    if(mij>=st_interv)
        maxim = max(maxim,query(st,mij,st_interv,dr_interv,2*nr));

    if(mij+1<=dr_interv)
        maxim=max(maxim,query(mij+1,dr,st_interv,dr_interv,2*nr+1));

    return maxim;
}

int get_lca(int a, int b)
{
    int i,j,k,st,dr;

    st=timp_euler[a];
    dr=timp_euler[b];

    if(st>dr)
        swap(st,dr);

    for(i=0;(1ll<<i)<=dr-st+1;i++);
    i--;

    j=rmq[i][st];
    k=rmq[i][dr-(1ll<<i)+1];

    if(depth[j]>depth[k])
        j=k;

    return j;

}


int get_max_hld(int inc, int fin)
{
    int maxim=-INF;
    while(depth[top[inc]]>=depth[fin])
    {
        // iau tot lantul heavy
        maxim=max(maxim,query(1,n,tin[top[inc]],tin[inc],1));
        inc = top[inc];

        if(inc==fin)
            break;

        inc = tata[inc];
    }

    // de la inc la fin
    maxim=max(maxim,query(1,n,tin[fin],tin[inc],1));
    return maxim;
}

int main()
{
    int m,i,j,k,t,q,nr,minim,maxim,suma, lca;

    fin>>n>>m;
    for(i=1;i<=n;i++)
    {
        fin>>val_init[i];
    }

    for(i=1;i<n;i++)
    {
        fin>>j>>k;
        graf[j].push_back(k);
        graf[k].push_back(j);
    }


    tin[0]=VMAX;
    dfs(1,0);
    decomp(1,1);
    euler_tour_lca.push_back(0);
    euler_lca_(1,0);


    for(i=1;i<euler_tour_lca.size();i++)
        rmq[0][i]=euler_tour_lca[i];

    for(i=1;(1ll<<i)<euler_tour_lca.size();i++)
    {
        for(j=1;(1ll<<i)+j-1<euler_tour_lca.size();j++)
        {
            rmq[i][j]=rmq[i-1][j];
            if(depth[rmq[i][j]]>depth[rmq[i-1][j+(1ll<<(i-1))]])
                rmq[i][j]=rmq[i-1][j+(1ll<<(i-1))];
        }
    }

    for(i=1;i<=n;i++)
    {
        update(1,n,tin[i],1,val_init[i]);
    }




    while(m--)
    {
        fin>>i>>j>>k;
        if(i==1)
        {
            update(1,n,tin[j],1,k);
        }
        else
        {
            lca=get_lca(j,k);
            maxim=get_max_hld(j,lca);
            maxim=max(maxim,get_max_hld(k,lca));
            fout<<maxim<<' ';
        }
    }


    return 0;
}