Cod sursa(job #3346281)

Utilizator Alex_at_gameIustin-Alexandru Frateanu Alex_at_game Data 13 martie 2026 08:58:02
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.07 kb
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
#define all(v) begin(v), end(v)
#define al(v, l, r) begin(v) + l, begin(v) + r + 1
#define sz(v) (int)v.size()
#define pb push_back
#define pob pop_back
#define fs first
#define sd second

constexpr int inf = 2e9;
constexpr ll infll = 4e18;
constexpr int N = 1e5 + 5;

struct aint {
    int n;
    vector<int> tr;

    aint(int n): n(n), tr(4 * n + 5, 0) {}

    void update(int nod, int l, int r, int p, int x) {
        if (l == r) {
            tr[nod] = x;
            return;
        }

        int mij = l + ((r  - l) >> 1);

        if (p <= mij) {
            update(nod << 1, l, mij, p, x);
        } else {
            update(nod << 1 | 1, mij + 1, r, p, x);
        }

        tr[nod] = max(tr[nod << 1], tr[nod << 1 | 1]);
    }

    int query(int nod, int l, int r, int a, int b) {
        if (b < l || r < a) {
            return 0;
        }

        if (a <= l && r <= b) {
            return tr[nod];
        }

        int mij = l + ((r - l) >> 1);
        return max(query(nod << 1, l, mij, a, b), query(nod << 1 | 1, mij + 1, r, a, b));
    }
};

int n, q, a[N], par[N], adc[N], heavy[N], head[N], poz[N], dim[N], curr_poz;
vector<int> g[N];

void dfs(int x, int p) {
    par[x] = p;
    dim[x] = 1;
    int mx = 0;

    for (int y : g[x]) {
        if (y == p) {
            continue;
        }

        adc[y] = adc[x] + 1;
        dfs(y, x);
        dim[x] += dim[y];

        if (mx < dim[y]) {
            heavy[x] = y;
            mx = dim[y];
        }
    }
}

void decomp(int x, int h) {
    head[x] = h;
    poz[x] = ++curr_poz;

    if (heavy[x]) {
        decomp(heavy[x], h);
    }

    for (int y : g[x]) {
        if (y == par[x] || y == heavy[x]) {
            continue;
        }

        decomp(y, y);
    }
}

int query_path(aint& seg, int a, int b) {
    int ans = 0;

    while (head[a] != head[b]) {
        if (adc[head[a]] < adc[head[b]]) {
            swap(a, b);
        }

        ans = max(ans, seg.query(1, 1, n, poz[head[a]], poz[a]));
        a = par[head[a]];
    }

    if (adc[a] > adc[b]) {
        swap(a, b);
    }

    ans = max(ans, seg.query(1, 1, n, poz[a], poz[b]));
    return ans;
}

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    freopen("heavypath.in", "r", stdin);
    freopen("heavypath.out", "w", stdout);

    cin >> n >> q;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }

    for (int i = 1, x, y; i < n; ++i) {
        cin >> x >> y;
        g[x].pb(y);
        g[y].pb(x);
    }

    dfs(1, 0);
    decomp(1, 0);
    aint seg(n);

    for (int i = 1; i <= n; ++i) {
        seg.update(1, 1, n, poz[i], a[i]);
    }

    for (int i = 0, t, x, y; i < q; ++i) {
        cin >> t >> x >> y;

        if (t == 0) {
            seg.update(1, 1, n, poz[x], y);
        } else {
            cout << query_path(seg, x, y) << "\n";
        }
    }
}