Cod sursa(job #3274089)

Utilizator tryharderulbrebenel mihnea stefan tryharderul Data 4 februarie 2025 23:19:29
Problema Heavy Path Decomposition Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.56 kb
#include <bits/stdc++.h>

using namespace std;

class HLD {
private:
    int n, nrPaths = 0, timer = 0;
    vector<vector<int>> tree;
    vector<int> sz, par, depth, child, tp, id;

    class Segtree {
    private:
        vector<int> tree;
    public:
        void init(int sz) {
            tree.resize(3 * sz);
        }
        void update(int node, int l, int r, int pos, int val) {
            if (l == r) {
                tree[node] = val;
                return;
            }
            int mid = (l + r) / 2;
            if (pos <= mid) { update(2 * node, l, mid, pos, val); }
            else { update(2 * node + 1, mid + 1, r, pos, val); }
            tree[node] = max(tree[2 * node], tree[2 * node + 1]);
        }
        int query(int node, int l, int r, int x, int y) {
            if (r < x || l > y) { return 0; }
            if (x <= l && r <= y) { return tree[node]; }
            int mid = (l + r) / 2;
            int left = query(2 * node, l, mid, x, y);
            int right = query(2 * node + 1, mid + 1, r, x, y);
            return max(left, right);
        }
    }st;

public:
    HLD(const vector<vector<int>> &g) {
        tree = g;
        n = (int)tree.size() - 1;
        sz.resize((int)tree.size());
        par.resize((int)tree.size());
        depth.resize((int)tree.size());
        child.resize((int)tree.size());
        tp.resize((int)tree.size());
        id.resize((int)tree.size());
        st.init((int)tree.size());
        dfs(1, 1);
        decompose(1, 1, 1);
        for (int i = 1; i <= n; i++) { cout << tp[i] << ' '; }
    }
    void dfs(int node, int parent) {
        sz[node] = 1;
        par[node] = parent;
        for (int son : tree[node]) {
            if (son == parent) { continue; }
            depth[son] = depth[node] + 1;
            dfs(son, node);
            sz[node] += sz[son];
        }
    }
    void decompose(int node, int parent, int top) {
        id[node] = ++timer;
        tp[node] = top;
        pair<int, int> child = {-1, -1};
        for (int son : tree[node]) {
            if (son == parent) { continue; }
            if (sz[son] > child.second) {
                child.first = son;
                child.second = sz[son];
            }
        }
        if (child.first == -1) { return; }
        decompose(child.first, node, top);
        for (int son : tree[node]) {
            if (son == parent || son == child.first) { continue; }
            decompose(son, node, son);
        }
    }
    void update(int idx, int val) {
        st.update(1, 1, n, id[idx], val);
    }
    int query(int x, int y) {
        int ans = 0;
        while (tp[x] != tp[y]) {
            if (depth[tp[x]] < depth[tp[y]]) { swap(x, y); }
            ans = max(ans, st.query(1, 1, n, id[tp[x]], id[x]));
            x = par[tp[x]];
        }
        if (depth[x] > depth[y]) { swap(x, y); }
        ans = max(ans, st.query(1, 1, n, id[x], id[y]));
        return ans;
    }
};

int main() {

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

    int n, q;
    in >> n >> q;

    vector<int> val(n + 1);
    for (int i = 1; i <= n; i++) {
        in >> val[i];
    }

    vector<vector<int>> tree(n + 1);
    for (int i = 1; i < n; i++) {
        int x, y;
        in >> x >> y;
        tree[x].push_back(y);
        tree[y].push_back(x);
    }

    HLD hld(tree);
    for (int i = 1; i <= n; i++) {
        hld.update(i, val[i]);
    }

    while (q--) {
        int type, x, y;
        in >> type >> x >> y;
        if (type == 0) {
            hld.update(x, y);
        } else {
            out << hld.query(x, y) << "\n";
        }

    }



    return 0;
}