Cod sursa(job #3338047)

Utilizator coco11coraline kalbfleisch coco11 Data 31 ianuarie 2026 11:23:58
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.73 kb
#include <bits/stdc++.h>
using namespace std;

const int NMAX = 100000;
int N, M;
vector<int> G[NMAX+1];
int parent[NMAX+1], depth[NMAX+1], heavy[NMAX+1], sz[NMAX+1];
int head[NMAX+1], pos[NMAX+1];
long long values[NMAX+1];
int curPos;

struct SegmentTree {
    vector<long long> tree;
    int n;
    SegmentTree(int n) : n(n) {
        tree.assign(4*n, 0);
    }
    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(qr < l || r < ql) return LLONG_MIN;
        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));
    }
};

SegmentTree *seg;

int dfs(int u) {
    sz[u] = 1;
    int maxSubtree = 0;
    for(int v : G[u]) {
        if(v == parent[u]) continue;
        parent[v] = u;
        depth[v] = depth[u] + 1;
        int subtree = dfs(v);
        sz[u] += subtree;
        if(subtree > maxSubtree) {
            maxSubtree = subtree;
            heavy[u] = v;
        }
    }
    return sz[u];
}

void decompose(int u, int h) {
    head[u] = h;
    pos[u] = ++curPos;
    seg->update(1, 1, N, pos[u], values[u]);
    if(heavy[u]) decompose(heavy[u], h);
    for(int v : G[u]) {
        if(v != parent[u] && v != heavy[u]) {
            decompose(v, v);
        }
    }
}

long long queryPath(int u, int v) {
    long long res = LLONG_MIN;
    while(head[u] != head[v]) {
        if(depth[head[u]] < depth[head[v]]) swap(u, v);
        res = max(res, seg->query(1, 1, N, pos[head[u]], pos[u]));
        u = parent[head[u]];
    }
    if(depth[u] > depth[v]) swap(u, v);
    res = max(res, seg->query(1, 1, N, pos[u], pos[v]));
    return res;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    freopen("heavypath.in", "r", stdin);
    freopen("heavypath.out", "w", stdout);

    cin >> N >> M;
    for(int i=1; i<=N; i++) cin >> values[i];
    for(int i=0; i<N-1; i++) {
        int a, b; cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }

    seg = new SegmentTree(N);
    dfs(1);
    decompose(1, 1);

    while(M--) {
        int t, x; long long y;
        cin >> t >> x >> y;
        if(t == 0) {
            seg->update(1, 1, N, pos[x], y);
        } else {
            cout << queryPath(x, (int)y) << "\n";
        }
    }
    return 0;
}