Cod sursa(job #3367243)

Utilizator JenJenCristache Ion JenJen Data 6 octombrie 2026 22:16:31
Problema Heavy Path Decomposition Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.31 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream cin ("heavypath.in");
ofstream cout ("heavypath.out");

int n, m;
int tree[400005];
vector <int> adj[100005];
int temp[100005];
int poz[100005];
int depth[100005];
int heavy[100005];
int dad[100005];
int head[100005];
int vec[100005];
int tim = 1;
void make(int nod, int st, int dr)
{
    if (st == dr)
    {
        tree[nod] = vec[st];
        return;
    }
    else
    {
        int mij = (st + dr) >> 1;

        make(nod << 1, st, mij);
        make(nod << 1 | 1, mij + 1, dr);

        tree[nod] = max(tree[nod << 1], tree[nod << 1 | 1]);
    }
}

void update(int nod, int st, int dr, int poz, int val)
{
    if (st == dr)
    {
        tree[nod] = val;
    } else
    {
        int mij = (st + dr) >> 1;

        if (poz <= mij) update(nod << 1, st, mij, poz, val);
        else update(nod << 1 | 1, mij + 1, dr, poz, val);

        tree[nod] = max(tree[nod << 1], tree[nod << 1 | 1]);
    }
}
int ans = -1;
void calc(int nod, int st, int dr, int a, int b)
{
    if (a <= st && dr <= b)
    {
        ans = max(ans, tree[nod]);
    } else
    {
        int mij = (st + dr) >> 1;

        if (a <= mij) calc(nod << 1, st, mij, a, b);
        if (b > mij) calc(nod << 1 | 1, mij + 1, dr, a, b);
    }
}
int dfs(int nod, int parinte)
{
    int sizeNod = 1;
    int maxx = 0;
    int sizeX = 0;

    heavy[nod] = -1;
    dad[nod] = parinte;
    for (const auto& x : adj[nod])
    {
        if (x != parinte)
        {
            depth[x] = depth[nod] + 1;
            sizeX = dfs(x, nod);

            sizeNod += sizeX;
            if (sizeX > maxx)
            {
                maxx = sizeX;
                heavy[nod] = x;
            }
        }
    }

    return sizeNod;
}

void decompose(int nod, int parinte, int cap)
{
    head[nod] = cap;
    poz[nod] = tim++;
    if (heavy[nod] != -1)
    {
        decompose(heavy[nod], nod, cap);
    }

    for (const auto& x : adj[nod])
    {
        if (x != parinte && heavy[nod] != x)
        {
            decompose(x, nod, x);
        }
    }
}

int query(int u, int v)
{
    int rez = 0;
    ans = -1;
    while (head[u] != head[v])
    {
        if (depth[head[u]] > depth[head[v]])
        {
            swap(u, v);
        }

        calc(1, 1, n, poz[head[v]], poz[v]);
        rez = max(rez, ans);
        v = dad[head[v]];
    }

    if (depth[u] > depth[v]) swap(u, v);
    calc(1, 1, n, poz[head[v]], poz[v]);
    rez = max(rez, ans);

    return rez;
}

int u, v;
int main()
{
    cin.tie(NULL);
    ios_base::sync_with_stdio(false);

    cin >> n >> m;

    for (int i = 1; i <= n; i++)
    {
        cin >> temp[i];
    }

    for (int i = 1; i < n; i++)
    {
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    depth[1] = 0;
    dfs(1, 0);

    decompose(1, 0, 1);
    for (int i = 1; i <= n; i++)
    {
        vec[poz[i]] = temp[i];
    }
    make(1, 1, n);

    for (int i = 0; i < m; i++)
    {
        int tip, x, y;
        cin >> tip >> x >> y;

        if (tip == 0)
        {
            update(1, 1, n, poz[x], y);
        }
        else
        {
            cout << query(x, y) << "\n";
        }
    }
    return 0;
}