Cod sursa(job #3291164)

Utilizator Ruxandra009Ruxandra Vasilescu Ruxandra009 Data 3 aprilie 2025 13:29:21
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.73 kb
#include <algorithm>
#include <fstream>
#include <vector>

using namespace std;

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

const int nmax = 1e5 + 5;

struct ceva{
    int dad, w, val, lant, deep, ind;
}v[nmax];

int n, q, aint[4 * nmax], lg[nmax], up[nmax][20], aux[nmax];
vector<int> l, vec[nmax];

bool cmp(int i, int j)
{
    if(v[i].lant != v[j].lant)
        return v[i].lant < v[j].lant;

    return v[i].deep < v[j].deep;
}

void dfs(int nod)
{
    int poz = 0, oki = 0, maxx = 0, nr = 0;
    for(auto x : vec[nod])
    {
        if(x == v[nod].dad)
            continue;

        v[x].dad = nod;
        v[x].deep = v[nod].deep + 1;
        up[x][0] = nod;

        for(int i = 1; i <= lg[v[x].deep]; i ++)
            up[x][i] = up[up[x][i - 1]][i - 1];

        dfs(x);

        oki = 1;

        if(maxx < v[x].w)
            maxx = v[x].w, nr = 1, poz = x;

        else if(maxx == v[x].w)
            nr ++;
    }

    if(!oki)
    {
        l.push_back(nod);
        v[nod].lant = l.size() - 1;
        v[nod].w = 1;
        return;
    }

    if(nr > 1)
        v[nod].w = maxx + 1;
    else
        v[nod].w = maxx;

    v[nod].lant = v[poz].lant;
    l[v[nod].lant] = nod;
}

int lca(int x, int y)
{
    if(v[x].deep > v[y].deep)
        swap(x, y);

    if(v[x].deep != v[y].deep)
    {
        int nr = v[y].deep - v[x].deep;
        for(int i = 0; i < 20; i ++)
            if((1<<i)&nr)
                y = up[y][i];
    }

    if(x == y)
        return x;

    for(int i = 20; i >= 0; i --)
        if(up[x][i] != up[y][i])
            x = up[x][i], y = up[y][i];

    return up[x][0];
}

void update(int nod, int st, int dr, int x, int val)
{
    if(st == dr)
        aint[nod] = val;
    else
    {
        int mij = (st + dr) / 2;

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

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

int query(int nod, int st, int dr, int x, int y)
{
    if(x <= st && dr <= y)
        return aint[nod];
    else
    {
        int mij = (st + dr) / 2, m1 = 0, m2 = 0;

        if(x <= mij)
            m1 = query(2 * nod, st, mij, x, y);
        if(y > mij)
            m2 = query(2 * nod + 1, mij + 1, dr, x, y);

        return max(m1, m2);
    }
}

int solv(int i, int j)
{
    if(v[i].lant == v[j].lant)
        return query(1, 1, n, v[i].ind, v[j].ind);

    int ans = query(1, 1, n, v[l[v[j].lant]].ind, v[j].ind);
    j = v[l[v[j].lant]].dad;

    return max(ans, solv(i, j));
}

int main()
{
    for(int i = 2; i <= nmax - 5; i ++) lg[i] = lg[i / 2] + 1;

    f >> n >> q;
    for(int i = 1; i <= n; i ++)
    {
        f >> v[i].val;
        aux[i] = i;
    }

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

    v[1].deep = 1;
    dfs(1);

    sort(aux + 1, aux + n + 1, cmp);

    for(int i = 1; i <= n; i ++)
        v[aux[i]].ind = i;

    for(int i = 1; i <= n; i ++)
        update(1, 1, n, v[i].ind, v[i].val);

    for(; q >= 1; q --)
    {
        int tip, x, y;
        f >> tip >> x >> y;
        if(tip == 0)
        {
            update(1, 1, n, v[x].ind, y);
            v[x].val = y;
        }

        else
        {
            int an = lca(x, y), ans;
            if(an == x || an == y)
            {
                if(an == y)
                    swap(x, y);
                ans = solv(x, y);
            }
            else
                ans = max(solv(an, x), solv(an, y));

            g << ans << '\n';
        }
    }
    return 0;
}