Cod sursa(job #3357980)

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

const int MAXN = 100005;

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

int n, m;
vector<int> g[MAXN];
long long v[MAXN];
int depth[MAXN], parent[MAXN], heavy[MAXN], head[MAXN], pos[MAXN];
int cur_pos = 0;

int dfs(int u) {
    int size = 1;
    int max_subtree = 0;
    for (int i = 0; i < g[u].size(); ++i) {
        int v = g[u][i];
        if (v != parent[u]) {
            parent[v] = u;
            depth[v] = depth[u] + 1;
            int subtree = dfs(v);
            size += subtree;
            if (subtree > max_subtree) {
                max_subtree = subtree;
                heavy[u] = v;
            }
        }
    }
    return size;
}

void decompose(int u, int h) {
    head[u] = h;
    pos[u] = ++cur_pos;
    if (heavy[u] != 0)
        decompose(heavy[u], h);
    for (int i = 0; i < g[u].size(); ++i) {
        int v = g[u][i];
        if (v != parent[u] && v != heavy[u])
            decompose(v, v);
    }
}

long long tree[4 * MAXN];

void build(int node, int l, int r) {
    if (l == r) {
        tree[node] = 0;
        return;
    }
    int mid = (l + r) / 2;
    build(node * 2, l, mid);
    build(node * 2 + 1, mid + 1, r);
    tree[node] = max(tree[node * 2], tree[node * 2 + 1]);
}

void update(int node, int l, int r, int idx, long long val) {
    if (l == r) {
        tree[node] = val;
        return;
    }
    int mid = (l + r) / 2;
    if (idx <= mid)
        update(node * 2, l, mid, idx, val);
    else
        update(node * 2 + 1, mid + 1, r, idx, val);
    tree[node] = max(tree[node * 2], tree[node * 2 + 1]);
}

long long query(int node, int l, int r, int ql, int qr) {
    if (ql > r || qr < l) return 0;
    if (ql <= l && r <= qr) return tree[node];
    int mid = (l + r) / 2;
    return max(query(node * 2, l, mid, ql, qr), query(node * 2 + 1, mid + 1, r, ql, qr));
}

long long query_path(int u, int v) {
    long long res = 0;
    for (; head[u] != head[v]; v = parent[head[v]]) {
        if (depth[head[u]] > depth[head[v]]) swap(u, v);
        res = max(res, query(1, 1, n, pos[head[v]], pos[v]));
    }
    if (depth[u] > depth[v]) swap(u, v);
    res = max(res, query(1, 1, n, pos[u], pos[v]));
    return res;
}

int main() {
    fin >> n >> m;
    for (int i = 1; i <= n; ++i)
        fin >> v[i];
    for (int i = 1; i < n; ++i) {
        int a, b;
        fin >> a >> b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    depth[1] = 1;
    parent[1] = 0;
    dfs(1);
    decompose(1, 1);
    build(1, 1, n);
    for (int i = 1; i <= n; ++i)
        update(1, 1, n, pos[i], v[i]);
    while (m--) {
        int t, x;
        long long y;
        fin >> t >> x >> y;
        if (t == 0) {
            v[x] = y;
            update(1, 1, n, pos[x], y);
        } else {
            fout << query_path(x, y) << '\n';
        }
    }
    return 0;
}