Cod sursa(job #3358022)

Utilizator TestLicenta123Test Test TestLicenta123 Data 13 iunie 2026 23:04:38
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.01 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;

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

const int NMAX = 100005;

int n, m;
int v[NMAX];
vector<int> g[NMAX];

int sz[NMAX], par[NMAX], lvl[NMAX];
int head[NMAX], pos[NMAX], chain[NMAX], ptr;
int tree[4 * NMAX], base[NMAX];

void dfs_size(int nod, int p) {
    sz[nod] = 1;
    par[nod] = p;
    for (int i = 0; i < (int)g[nod].size(); ++i) {
        int fiu = g[nod][i];
        if (fiu != p) {
            lvl[fiu] = lvl[nod] + 1;
            dfs_size(fiu, nod);
            sz[nod] += sz[fiu];
        }
    }
}

void dfs_hld(int nod, int p, int cap) {
    head[nod] = cap;
    pos[nod] = ++ptr;
    chain[nod] = cap;
    int heavy = -1;
    for (int i = 0; i < (int)g[nod].size(); ++i) {
        int fiu = g[nod][i];
        if (fiu != p) {
            if (heavy == -1 || sz[fiu] > sz[heavy])
                heavy = fiu;
        }
    }
    if (heavy != -1)
        dfs_hld(heavy, nod, cap);
    for (int i = 0; i < (int)g[nod].size(); ++i) {
        int fiu = g[nod][i];
        if (fiu != p && fiu != heavy) {
            dfs_hld(fiu, nod, fiu);
        }
    }
}

void build(int nod, int st, int dr) {
    if (st == dr) {
        tree[nod] = base[st];
        return;
    }
    int mid = (st + dr) / 2;
    build(nod * 2, st, mid);
    build(nod * 2 + 1, mid + 1, dr);
    tree[nod] = max(tree[nod * 2], tree[nod * 2 + 1]);
}

void update(int nod, int st, int dr, int poz, int val) {
    if (st == dr) {
        tree[nod] = val;
        return;
    }
    int mid = (st + dr) / 2;
    if (poz <= mid)
        update(nod * 2, st, mid, poz, val);
    else
        update(nod * 2 + 1, mid + 1, dr, poz, val);
    tree[nod] = max(tree[nod * 2], tree[nod * 2 + 1]);
}

int query(int nod, int st, int dr, int l, int r) {
    if (l <= st && dr <= r)
        return tree[nod];
    int mid = (st + dr) / 2;
    int ans = -1;
    if (l <= mid)
        ans = max(ans, query(nod * 2, st, mid, l, r));
    if (r > mid)
        ans = max(ans, query(nod * 2 + 1, mid + 1, dr, l, r));
    return ans;
}

int query_hld(int x, int y) {
    int ans = -1;
    while (head[x] != head[y]) {
        if (lvl[head[x]] < lvl[head[y]])
            swap(x, y);
        int cap = head[x];
        ans = max(ans, query(1, 1, n, pos[cap], pos[x]));
        x = par[cap];
    }
    if (lvl[x] > lvl[y])
        swap(x, y);
    ans = max(ans, query(1, 1, n, pos[x], pos[y]));
    return ans;
}

int main() {
    in >> n >> m;
    for (int i = 1; i <= n; ++i)
        in >> v[i];
    for (int i = 1; i < n; ++i) {
        int a, b;
        in >> a >> b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    lvl[1] = 1;
    dfs_size(1, 0);
    ptr = 0;
    dfs_hld(1, 0, 1);
    for (int i = 1; i <= n; ++i)
        base[pos[i]] = v[i];
    build(1, 1, n);
    for (int i = 1; i <= m; ++i) {
        int t, x, y;
        in >> t >> x >> y;
        if (t == 0) {
            update(1, 1, n, pos[x], y);
        } else {
            out << query_hld(x, y) << '\n';
        }
    }
    return 0;
}