Cod sursa(job #3350766)

Utilizator SergiuS3003Sergiu Stancu Nicolae SergiuS3003 Data 12 aprilie 2026 18:07:53
Problema Heavy Path Decomposition Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.14 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
vector<int> aint, v, heavy, values(1), nodePos;
int N, Q;

void build(int x, int lx, int rx)
{
    if (lx == rx)
    {
        if (lx <= N)
            aint[x] = values[lx];
        return;
    }
    int mid = (lx + rx) / 2;
    build(2 * x, lx, mid);
    build(2 * x + 1, mid + 1, rx);
    aint[x] = max(aint[2 * x], aint[2 * x + 1]);
}

void update(int x, int lx, int rx, int poz, int val)
{
    if (lx == rx)
    {
        aint[x] = val;
        return;
    }
    int mid = (lx + rx) / 2;
    if (poz <= mid)
    {
        update(2 * x, lx, mid, poz, val);
    }
    else
        update(2 * x + 1, mid + 1, rx, poz, val);
    aint[x] = max(aint[2 * x], aint[2 * x + 1]);
}

int query(int x, int lx, int rx, int l, int r)
{
    if (rx < l || lx > r)
        return 0;
    if (lx >= l && rx <= r)
        return aint[x];
    int mid = (lx + rx) / 2;
    return max(query(2 * x, lx, mid, l, r), query(2 * x + 1, mid + 1, rx, l, r));
}

vector<int> sz, pathHead, level, p;

void dfs(int node, int parent, const vector<vector<int>> &G)
{
    sz[node] = 1;
    p[node] = parent;
    int szChildMax = 0, childMax = 0;
    for (auto child: G[node])
    {
        if (child == parent)
            continue;
        level[child] = level[node] + 1;
        dfs(child, node, G);
        if (sz[child] > szChildMax)
        {
            szChildMax = sz[child];
            childMax = child;
        }
        sz[node] += sz[child];
    }
    heavy[node] = childMax;
}

void decompose(int node, int crtHead, const vector<vector<int>> &G)
{
    pathHead[node] = crtHead;
    nodePos[node] = values.size();
    values.push_back(v[node]);
    if (heavy[node] != 0)
    {
        decompose(heavy[node], crtHead, G);
    }
    for (auto child: G[node])
    {
        if (child != heavy[node] && child != p[node])
        {
            decompose(child, child, G);
        }
    }
}

int main()
{
    f >> N >> Q;
    vector<vector<int>> G(N + 1);
    aint.resize(4 * N, 0);
    heavy.resize(N + 1, 0);
    v.resize(N + 1);
    level.resize(N + 1);
    level[1] = 1;
    pathHead.resize(N + 1);
    p.resize(N + 1);
    nodePos.resize(N + 1);
    for (int i = 1; i <= N; i++)
    {
        f >> v[i];
    }
    for (int i = 1; i < N; i++)
    {
        int x, y;
        f >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    sz.resize(N + 1);
    dfs(1, 0, G);
    decompose(1, 1, G);
    build(1, 1, N);
    while (Q--)
    {
        int tip, x, y;
        f >> tip >> x >> y;
        if (tip == 0)
        {
            update(1, 1, N, nodePos[x], y);
        }
        else
        {
            int mxCrt = 0;
            for (; pathHead[x] != pathHead[y]; x = p[pathHead[x]])
            {
                if (level[x] < level[y])
                    swap(x, y);
                mxCrt = max(mxCrt, query(1, 1, N, nodePos[pathHead[x]], nodePos[x]));
            }
            if (level[x] > level[y])
                swap(x, y);
            mxCrt = max(mxCrt, query(1, 1, N, nodePos[x], nodePos[y]));
            g << mxCrt << '\n';
        }
    }
    return 0;
}