Cod sursa(job #2585173)

Utilizator victorv88Veltan Victor victorv88 Data 18 martie 2020 18:36:08
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.79 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("heavypath.in");
ofstream g("heavypath.out");

int n, m, valori[100005], a, b, tata[100005], adancime[100005], subarbore[100005], interval[400005];
int boss[100005], id[100005], ultim, c;

vector<int>graph[100005];

void parcurgere(int nod, int parinte, int nivel)
{
    tata[nod]=parinte;
    adancime[nod]=nivel;
    subarbore[nod]=1;

    for (auto &v:graph[nod])
    {
        if (v!=parinte)
        {
            parcurgere(v,nod,nivel+1);

            subarbore[nod]+=subarbore[v];
        }
    }
}

void descompunere(int nod, int sus)
{
    ultim++;
    boss[nod]=sus;
    id[nod]=ultim;

    int copil=-1;
    for (auto &v:graph[nod])
    {
        if (v!=tata[nod])
        {
            if(copil==-1)
                copil=v;
            else
            {
                if (subarbore[v]>subarbore[copil])
                    copil=v;
            }
        }
    }

    if (copil!=-1)
        descompunere(copil,sus);

    for (auto &v:graph[nod])
    {
        if (v!=tata[nod] && v!=copil)
            descompunere(v,v);
    }
}

void addInterval(int nod, int st, int dr, int valoare, int ind)
{
    if (st==dr)
    {
        interval[nod]=valoare;
        return;
    }
    int mij=(st+dr)/2;
    if(ind<=mij)
        addInterval(nod*2,st,mij,valoare,ind);
    else
        addInterval(nod*2+1,mij+1,dr,valoare,ind);
    interval[nod]=max(interval[2*nod],interval[2*nod+1]);
}

int queryInterval(int nod, int st, int dr, int vs, int vd)
{
    if(vs<=st && dr<=vd)
        return interval[nod];
    int mij=(st+dr)/2;
    int rezst=-1, rezdr=-1;

    if(mij>=vs)
        rezst=queryInterval(nod*2,st,mij,vs,vd);
    if(mij<vd)
        rezdr=queryInterval(nod*2+1,mij+1,dr,vs,vd);

    return max(rezdr,rezst);
}

int solve(int a, int b, int n)
{
    if(boss[a]==boss[b])
    {
        if(id[a]>id[b])
            swap(a,b);
        return queryInterval(1,1,n,id[a],id[b]);
    }
    else
    {
        if(adancime[boss[a]]<adancime[boss[b]])
            swap(a,b);
        return max(queryInterval(1,1,n,id[boss[a]],id[a]),solve(tata[boss[a]],b,n));
    }
}

int main()
{
    f >> n >> m;
    for (int i=1; i<=n;  ++i)
        f >> valori[i];

    for (int i=1; i<n; ++i)
    {
        f >> a >> b;
        graph[a].push_back(b);
        graph[b].push_back(a);
    }

    parcurgere(1,0,1);
    descompunere(1,1);

    for (int i=1; i<=n; ++i)
    {
        addInterval(1,1,n,valori[i],id[i]);
    }
    for (int test=1; test<=m; ++test)
    {

        f >>c >> a >> b;
        if(c==0)
        {
            valori[a]=b;
            addInterval(1,1,n,b,id[a]);
        }
        else
            g << solve(a,b,n) << '\n';
    }
    return 0;
}