Cod sursa(job #3340180)

Utilizator rares89_Dumitriu Rares rares89_ Data 12 februarie 2026 15:21:42
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.16 kb
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <fstream>
#define INF 0x3f3f3f3f

using namespace std;

const int MAXN = 100005;

int N, M;
int vals[MAXN];
vector<int> adj[MAXN];

int parent[MAXN], depth[MAXN], sz[MAXN];
int heavy[MAXN], head[MAXN], pos[MAXN];
int arr[MAXN];
int tree[4 * MAXN];
int cur_pos;

void dfs_sz(int u, int p, int d) {
    sz[u] = 1;
    parent[u] = p;
    depth[u] = d;
    int max_sz = -1;
    heavy[u] = -1;

    for (int v : adj[u]) {
        if (v != p) {
            dfs_sz(v, u, d + 1);
            sz[u] += sz[v];
            if (sz[v] > max_sz) {
                max_sz = sz[v];
                heavy[u] = v;
            }
        }
    }
}

void dfs_hld(int u, int h) {
    head[u] = h;
    pos[u] = ++cur_pos;
    arr[cur_pos] = vals[u];

    if (heavy[u] != -1) {
        dfs_hld(heavy[u], h);
    }

    for (int v : adj[u]) {
        if (v != parent[u] && v != heavy[u]) {
            dfs_hld(v, v);
        }
    }
}

void build(int node, int start, int end) {
    if (start == end) {
        tree[node] = arr[start];
    } else {
        int mid = (start + end) / 2;
        build(2 * node, start, mid);
        build(2 * node + 1, mid + 1, end);
        tree[node] = max(tree[2 * node], tree[2 * node + 1]);
    }
}

void update_tree(int node, int start, int end, int idx, int val) {
    if (start == end) {
        tree[node] = val;
    } else {
        int mid = (start + end) / 2;
        if (start <= idx && idx <= mid) {
            update_tree(2 * node, start, mid, idx, val);
        } else {
            update_tree(2 * node + 1, mid + 1, end, idx, val);
        }
        tree[node] = max(tree[2 * node], tree[2 * node + 1]);
    }
}

int query_tree(int node, int start, int end, int l, int r) {
    if (r < start || end < l) {
        return -1;
    }
    if (l <= start && end <= r) {
        return tree[node];
    }
    int mid = (start + end) / 2;
    return max(query_tree(2 * node, start, mid, l, r),
               query_tree(2 * node + 1, mid + 1, end, l, r));
}

int query_path(int u, int v) {
    int res = -1;
    for (; head[u] != head[v]; u = parent[head[u]]) {
        if (depth[head[u]] < depth[head[v]]) swap(u, v);
        res = max(res, query_tree(1, 1, N, pos[head[u]], pos[u]));
    }
    if (depth[u] > depth[v]) swap(u, v);
    res = max(res, query_tree(1, 1, N, pos[u], pos[v]));
    return res;
}

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

    fin >> N >> M;

    for (int i = 1; i <= N; ++i) {
        fin >> vals[i];
    }

    for (int i = 0; i < N - 1; ++i) {
        int u, v;
        fin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    cur_pos = 0;
    dfs_sz(1, 0, 0);
    dfs_hld(1, 1);
    build(1, 1, N);

    for (int i = 0; i < M; ++i) {
        int op, x, y;
        fin >> op >> x >> y;
        if (op == 0) {
            update_tree(1, 1, N, pos[x], y);
            vals[x] = y;
        } else {
            fout << query_path(x, y) << "\n";
        }
    }

    fin.close();

    return 0;
}