Cod sursa(job #2839302)

Utilizator stefanvoicaVoica Stefan stefanvoica Data 25 ianuarie 2022 19:11:53
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.63 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fin ("heavypath.in");
ofstream fout("heavypath.out");
const int dim = 100002;
vector <int> a[dim];
int w[dim], h[dim], dad[dim], hh[dim], pos[dim], pos2[dim], k, aint[4 * dim], val[dim], n;

void dfs1 (int x, int tata = 0)
{
    dad[x] = tata;
    w[x] = 1;
    h[x] = h[tata] + 1;
    for (int y : a[x])
        if (y != tata)
        {
            dfs1 (y, x);
            w[x] += w[y];
        }
}


void dfs2 (int x)
{
    pos[x] = ++k;
    pos2[k] = x;
    int maxi = 0, ind = 0;

    for (int y : a[x])
        if (y != dad[x] && w[y] > maxi)
        {
            maxi = w[y];
            ind = y;
        }
    if (ind == 0)
        return;
    hh[ind] = hh[x];
    dfs2 (ind);
    for (int y : a[x])
        if (y != dad[x] && y != ind)
        {
            hh[y] = y;
            dfs2(y);
        }
}

void build (int nod, int st, int dr)
{
    if (st == dr)
        aint[nod] = val[pos2[st]];
    else {
        int mij = (st + dr)/2;
        build (2 * nod, st, mij);
        build (2 * nod + 1, mij + 1, dr);
        aint[nod] = max(aint[2*nod], aint[2*nod+1]);
    }
}

void update (int nod, int st, int dr, int poz, int value)
{
    if (st == dr)
        aint[nod] = value;
    else {
        int mij = (st + dr)/2;
        if (poz <= mij)
            update (2 * nod, st, mij, poz, value);
        else
            update (2 * nod + 1, mij + 1, dr, poz, value);
        aint[nod] = max(aint[2*nod], aint[2*nod+1]);
    }
}

int query (int nod, int st, int dr, int l, int r)
{
    if (dr < l || r < st)
        return 0;
    if (l <= st && dr <= r)
        return aint[nod];
    else {
        int mij = (st + dr)/2;
        return max(query(2*nod, st, mij, l, r), query(2*nod+1, mij+1, dr, l, r));
    }
}

int Query_heavy (int x, int y)
{
    if (hh[x] == hh[y])
        return query(1, 1, n, min(pos[x], pos[y]), max(pos[x], pos[y]));
    if (h[hh[x]] < h[hh[y]])
        swap (x, y);
    int t = query (1, 1, n, pos[hh[x]], pos[x]);
    x = dad[hh[x]];
    return max(t, Query_heavy(x, y));
}

int main()
{
    int q, tip, x, y;
    fin >> n >> q;

    for (int i = 1; i <= n; i++)
        fin >> val[i];

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

    dfs1 (1);
    hh[1] = 1;
    dfs2 (1);

    build (1, 1, n);
    while (q--)
    {
        fin >> tip >> x >> y;
        if (tip == 0)
            update(1, 1, n, pos[x], y);
        else
            fout << Query_heavy (x, y) << '\n';
    }
}