Cod sursa(job #2866794)

Utilizator Cosmin2004_InfoMoldoveanu Cosmin Cosmin2004_Info Data 9 martie 2022 23:23:35
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.52 kb
#include <bits/stdc++.h>

using namespace std;
class HeavyLight {
    int n, k;
    vector <vector <int>>& g;
    vector <int> depth, sz, path, trans, head, t;
    vector <vector <int>> comp;
    void dfs(int u, int p) {
        depth[u] = depth[p] + 1;
        int link = 0;
        for(int v : g[u]) if(v != p) {
            dfs(v, u);
            sz[u] += sz[v];
            if(sz[v] > sz[link])
                link = v;
        }
        for(int v : g[u]) if(v != p && v != link)
            head[path[v]] = u;
        path[u] = link ? path[link] : k++;
        comp[path[u]].push_back(u);
    }
    int heavy_query(int l, int r) {
        int res = 0;
        for(l += n, r += n; l < r; l >>= 1, r >>= 1) {
            if(l & 1) res = max(res, t[l++]);
            if(r & 1) res = max(res, t[--r]);
        }
        return res;
    }
    void heavy_update(int pos, int val) {
        for(t[pos += n] = val; pos > 1; pos >>= 1)
            t[pos >> 1] = max(t[pos], t[pos ^ 1]);
    }
public:
    HeavyLight(int n, int* val, vector <vector <int>>& _g) : n(n), k(0), g(_g), depth(n + 1, 0), sz(n + 1, 1), path(n + 1, 0), trans(n + 1, 0), head(n + 1, 0), t(2 * n, 0), comp(n + 1) {
        dfs(1, 0);
        for(int i = 0, cnt = 0; i < k; i++)
            for(int c : comp[i]) {
                t[cnt + n] = val[c];
                trans[c] = cnt++;
            }
        for(int i = n - 1; i > 0; i--)
            t[i] = max(t[i << 1], t[i << 1 | 1]);
    }
    void update(int x, int y) { heavy_update(trans[x], y); }
    int query(int x, int y) {
        int res = 0;
        for(; path[x] != path[y]; x = head[path[x]]) {
            if(depth[head[path[x]]] < depth[head[path[y]]]) swap(x, y);
            res = max(res, heavy_query(trans[x], trans[comp[path[x]].back()] + 1));
        }
        if(trans[x] > trans[y]) swap(x, y);
        return max(res, heavy_query(trans[x], trans[y] + 1));
    }
};
const int N = 1e5;
int val[N + 5];
vector <vector <int>> g;

int main()
{
    ifstream cin("heavypath.in");
    ofstream cout("heavypath.out");
    int n, m, u, v;
    cin >> n >> m;
    g.resize(n + 1);
    for(int i = 1; i <= n; i++)
        cin >> val[i];
    for(int i = 1; i < n; i++)
        cin >> u >> v,
        g[u].push_back(v),
        g[v].push_back(u);
    HeavyLight HLD(n, val, g);
    for(int i = 1; i <= m; i++) {
        int t, x, y;
        cin >> t >> x >> y;
        if(t == 0) HLD.update(x, y);
        else cout << HLD.query(x, y) << "\n";
    }
    return 0;
}