Cod sursa(job #3364039)

Utilizator pkseVlad Bondoc pkse Data 27 august 2026 16:15:22
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.55 kb
#include <bits/stdc++.h>
#define pb push_back
using namespace std;

const int nmax = 100'000, inf = 1'000'000'000;

struct aint {
    aint(int n = 0) : n(n) {}
    int n, a[2 * nmax];

    void update(int p, int v) {
        assert(p < n);
        a[p += n] = v;
        for(p >>= 1; p; p >>= 1) {
            a[p] = max(a[p << 1], a[p << 1 | 1]);
        }
    }

    int query(int l, int r) {
        int ans = -inf;
        for(l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
            if(l & 1) ans = max(ans, a[l ++]);
            if(r & 1) ans = max(a[-- r], ans);
        }
        return ans;
    }
} t(nmax);

int n, q;

int a[nmax];
vector<int> adj[nmax];
int sz[nmax], depth[nmax], pa[nmax];

int in[nmax], timer = 0;
int heavy_root[nmax];

void initdfs(int u = 0, int p = 0) {
    sz[u] = 1, pa[u] = p;
    for(auto &v : adj[u]) {
        if(v == p) continue;
        depth[v] = 1 + depth[u];
        initdfs(v, u);
        sz[u] += sz[v];
    }
}

void dfs(int u = 0, int p = 0) {
    in[u] = timer ++;
    t.update(in[u], a[u]);
    if(adj[u].size() + (u ? -1 : 0) < 1)
        return;
    nth_element(adj[u].begin(), adj[u].begin(), adj[u].end(), [&](int x, int y){
        if(x == p) return false;
        if(y == p) return true;
        return sz[x] > sz[y];
    });
    {
        int v = adj[u][0];
        heavy_root[v] = heavy_root[u];
        dfs(v, u);
    }
    for(int i = 1; i < adj[u].size(); i ++) {
        int v = adj[u][i];
        if(v == p)
            continue;
        heavy_root[v] = v;
        dfs(v, u);
    }
}

int query(int u, int v) {
    int ans = -inf;
    while(heavy_root[u] != heavy_root[v]) {
        if(depth[heavy_root[u]] < depth[heavy_root[v]])
            swap(u, v);
        ans = max(ans, t.query(in[heavy_root[u]], in[u]));
        u = pa[heavy_root[u]];
    }
    if(in[u] > in[v])
        swap(u, v);
    ans = max(ans, t.query(in[u], in[v]));
    return ans;
}

int main() {
    ifstream cin("heavypath.in");
    ofstream cout("heavypath.out");
    cin.tie(0)->sync_with_stdio(0);
    cin >> n >> q;
    for(int i = 0; i < n; i ++) {
        cin >> a[i];
    }
    for(int i = 0; i < n - 1; i ++) {
        int u, v; cin >> u >> v; u --; v --;
        adj[u].pb(v), adj[v].pb(u);
    }
    initdfs();
    dfs();
    for(; q --;) {
        int typ, x, y; cin >> typ >> x >> y;
        if(typ == 0) {
            x --;
            t.update(in[x], y);
        } else {
            x --; y --;
            cout << query(x, y) << '\n';
        }
    }
}