Cod sursa(job #2977943)

Utilizator DKMKDMatei Filibiu DKMKD Data 12 februarie 2023 17:42:43
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.03 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

const int NMAX = 2e5 + 5;

vector<int>v[NMAX];

int a[NMAX];
int depth[NMAX];
int aint[4 * NMAX];
int t[NMAX];
int sarb[NMAX];
int ti[NMAX];
int ind[NMAX];
int v1[NMAX];
int kon;
int n;

void dfs1(int p, int tata)
{
    sarb[p] = 1;
    ind[p] = p;
    t[p] = tata;
    depth[p] = depth[tata] + 1;
    for (auto i : v[p])
    {
        if (tata != i)
        {
            dfs1(i, p);
            sarb[p] += sarb[i];
        }
    }
}

void dfs2(int p)
{
    int maxim = -1, hc = -1;
    ti[p] = ++kon;
    for (auto i : v[p])
    {
        if (t[p] != i)
        {
            if (maxim < sarb[i])
            {
                maxim = sarb[i];
                hc = i;
            }
        }
    }
    if (hc < 0)
        return;
    else
    {
        ind[hc] = ind[p];
        dfs2(hc);
        for (auto i : v[p])
            if (i != t[p] && i != hc)
                dfs2(i);
    }
}

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

void update(int p, int st, int dr, int a, int b)
{
    int mij;
    if (st == dr)
    {
        aint[p] = b;
        return;
    }
    else
    {
        mij = st + dr;
        mij /= 2;
        if (a <= mij)
            update(2 * p, st, mij, a, b);
        else
            update(2 * p + 1, mij + 1, dr, a, b);
        aint[p] = max(aint[2 * p], aint[2 * p + 1]);
    }
}

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

int solve(int a, int b)
{
    if (ind[a] == ind[b])
    {
        if (ti[a] > ti[b])
            swap(a, b);
        return query(1, 1, n, ti[a], ti[b]);
    }
    if (depth[ind[a]] < depth[ind[b]])
        swap(a, b);
    int aux = solve(t[ind[a]], b);
    return max(query(1, 1, n, ti[ind[a]], ti[a]), aux);
}

int main()
{
    int m, i, j, q, x, y, t;
    fin >> n >> q;
    for (i = 1; i <= n; i++)
        fin >> a[i];
    for (i = 1; i < n; i++)
    {
        fin >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs1(1, 0);
    dfs2(1);
    for (i = 1; i <= n; i++)
        v1[ti[i]] = a[i];
    build(1, 1, n);
    while (q--)
    {
        fin >> t >> x >> y;
        if (t == 0)
            update(1, 1, n, ti[x], y);
        if (t == 1)
            fout << solve(x, y) << "\n";
    }
    return 0;
}