Cod sursa(job #2784557)

Utilizator Edyci123Bicu Codrut Eduard Edyci123 Data 16 octombrie 2021 18:50:06
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.7 kb
#include <bits/stdc++.h>
#define DIM 100005

using namespace std;

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

int n, q, nrLanturi, v[DIM], t[DIM], desc[DIM], depth[DIM], nrLant[DIM], aint[4 * DIM], Start[DIM], P[DIM];
vector <int> lant[DIM];
vector <int> edges[DIM];
bitset <DIM> used;

void dfs(int nod, int niv, int tata)
{
    used[nod] = 1;
    depth[nod] = niv;
    desc[nod] = 1;
    int maxDesc = 0, fiuMaxDesc;

    for(auto child : edges[nod])
        if(!used[child])
        {
            dfs(child, niv + 1, nod);
            desc[nod] += desc[child];
            if(maxDesc < desc[child])
            {
                maxDesc = desc[child];
                fiuMaxDesc = child;
            }
        }

    if(maxDesc == 0)
    {
        lant[++nrLanturi].push_back(nod);
        nrLant[nod] = nrLanturi;
        t[nrLanturi] = tata;
    }
    else
    {
        lant[nrLant[fiuMaxDesc]].push_back(nod);
        nrLant[nod] = nrLant[fiuMaxDesc];
        t[nrLant[fiuMaxDesc]] = tata;
    }

}

void Update(int nod, int st, int dr, int poz, int val, int decalaj)
{
    if(st == dr)
    {
        aint[nod + decalaj] = val;
        return ;
    }

    int mid = (st + dr) / 2;
    if(mid >= poz)
        Update(2 * nod, st, mid, poz, val, decalaj);
    else
        Update(2 * nod + 1, mid + 1, dr, poz, val, decalaj);

    aint[nod + decalaj] = max(aint[2 * nod + decalaj], aint[2 * nod + 1 + decalaj]);
}

int Query(int nod, int st, int dr, int stQ, int drQ, int decalaj)
{
    if(stQ <= st && dr <= drQ)
    {
        return aint[nod + decalaj];
    }

    int mid = (st + dr) / 2, r1(0), r2(0);
    if(mid >= stQ)
        r1 = Query(2 * nod, st, mid, stQ, drQ, decalaj);
    if(mid < drQ)
        r2 = Query(2 * nod + 1, mid + 1, dr, stQ, drQ, decalaj);

    return max(r1, r2);
}

int main()
{
    f >> n >> q;

    for(int i = 1; i <= n; i++)
        f >> v[i];

    for(int i = 1; i < n; i++)
    {
        int x, y;
        f >> x >> y;
        edges[x].push_back(y);
        edges[y].push_back(x);
    }

    dfs(1, 1, 0);

    for(int i = 1; i <= nrLanturi; i++)
    {
        int j, k;
        Start[i] = Start[i - 1] + 4 * lant[i - 1].size();
        for(j = 0, k = lant[i].size() - 1; j < k; j++, k--)
        {
            swap(lant[i][j], lant[i][k]);
            P[lant[i][j]] = j;
            P[lant[i][k]] = k;
        }
        P[lant[i][j]] = j;
    }

    for(int i = 1; i <= n; i++)
        Update(1, 0, lant[nrLant[i]].size() - 1, P[i], v[i], Start[nrLant[i]]);

    for(; q; q--)
    {
        int ops, x, y;
        f >> ops >> x >> y;
        if(ops == 0)
        {
            Update(1, 0, lant[nrLant[x]].size() - 1, P[x], y, Start[nrLant[x]]);
        }
        else
        {
            int ans = 0;
            while(1)
            {
                int l1 = nrLant[x];
                int l2 = nrLant[y];

                if(l1 == l2)
                {
                    ans = max(ans, Query(1, 0, lant[l1].size() - 1, min(P[x], P[y]), max(P[x], P[y]), Start[l1]));
                    break;
                }
                else
                {
                    if(depth[t[l1]] > depth[t[l2]])
                    {
                        ans = max(ans, Query(1, 0, lant[l1].size() - 1, 0, P[x], Start[l1]));
                        x = t[l1];
                    }
                    else
                    {
                        ans = max(ans, Query(1, 0, lant[l2].size() - 1, 0, P[y], Start[l2]));
                        y = t[l2];
                    }

                }
            }
            g << ans << "\n";
        }
    }

    return 0;
}