Cod sursa(job #2866546)

Utilizator Cosmin2004_InfoMoldoveanu Cosmin Cosmin2004_Info Data 9 martie 2022 19:40:14
Problema Heavy Path Decomposition Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.3 kb
#include <bits/stdc++.h>

using namespace std;
template <typename T> class Segtree {
public:
    int n, k; vector <T> t; T neutral;
    function <T (T, T)> f;
    Segtree(int n, T neu, function <T (T, T)> _f) : n(n), k(0), t(2 * n, neu), neutral(neu), f(_f) {}
    void push(T val) { t[n + (k++)] = val; }
    void build() {
        for(int i = n - 1; i > 0; i--)
            t[i] = f(t[i << 1], t[i << 1 | 1]);
    }
    void update(int pos, T val) {for(t[pos += n] = val; pos > 1; pos >>= 1) t[pos >> 1] = f(t[pos], t[pos ^ 1]);}
    T query(int l, int r) { /// on interval [l, r), indexed from 0
        T resl(neutral), resr(neutral);
        for(l += n, r += n; l < r; l >>= 1, r >>= 1) {
            if(l & 1) resl = f(resl, t[l++]);
            if(r & 1) resr = f(t[--r], resr);
        }
        return f(resl, resr);
    }
};

template <typename T>
class HeavyLight {
    int n, timer;
    vector <vector <int>>& g;
    vector <int> sz, head, par, link, h, tin, lg2, rev;
    vector <vector <int>> e;
    vector <T> val;
    function <T(T, T)> f; T neutral;
    vector <Segtree <T>> HP;
    void decompose(int u, int p) {
        par[u] = p;
        sz[u] = 1;
        int mx = 0;
        tin[u] = ++timer;
        rev[tin[u]] = u;
        e[tin[u]][0] = tin[u];
        for(int v : g[u]) if(v != p) {
            decompose(v, u);
            sz[u] += sz[v];
            if(sz[v] > sz[mx])
                mx = v;
        }
        link[u] = mx;
        h[u] = h[link[u]] + 1;
        head[mx] = u;
        e[++timer][0] = tin[p];
    }
    void build(int u) {
        int v = link[u];
        if(!head[u]) {
            HP.emplace_back(h[u], neutral, f);
            h[u] = 0;
            head[u] = u;
            link[u] = HP.size() - 1;
        } else {
            h[u] = h[head[u]] + 1;
            link[u] = link[head[u]];
            head[u] = head[head[u]];
        }
        HP[link[u]].push(val[u]);
        if(v) build(v);
        if(head[u] == u)
            HP[link[u]].build();
    }
    int LCA(int x, int y) {
        x = tin[x], y = tin[y];
        if(x > y) swap(x, y);
        int l = lg2[y - x + 1];
        return rev[min(e[x][l], e[y - (1 << l) + 1][l])];
    }
public:
    template <typename Iterator>
    HeavyLight(vector <vector <int>>& _g, Iterator first, Iterator last, auto _f, T neut) : n(last - first), timer(0), g(_g), val(n + 1), sz(n + 1, 0),
                                        head(n + 1, 0), par(n + 1, 0), link(n + 1, 0), h(n + 1, 0), tin(n + 1, 0), lg2(2 * n + 1, 0), e(2 * n + 1), rev(2 * n + 1, 0), f(_f), neutral(neut) {
        int l = 32 - __builtin_clz(n);
        for(int i = 1; i <= 2 * n; i++) e[i].resize(l, 0);
        for(int i = 2; i <= 2 * n; i++)
            lg2[i] = lg2[i >> 1] + 1;
        for(auto it = first; it != last; it++)
            val[it - first + 1] = *it;
        decompose(1, 0);
        for(int j = 1; j <= l; j++)
            for(int i = 1; i <= 2 * n; i++)
                if(i + (1 << j) <= 2 * n)
                    e[i][j] = min(e[i][j - 1], e[i + (1 << j - 1)][j - 1]);
        for(int i = 1; i <= n; i++) if(!head[i])
            build(i);
    }
    void update(int x, T y) {
        HP[link[x]].update(h[x], y);
    }
    T query_vertical(int x, int r) {
        if(x == r) return neutral;
        if(head[x] == head[r]) return HP[link[x]].query(h[r] + 1, h[x] + 1);
        return f(HP[link[x]].query(0, h[x] + 1), query_vertical(par[head[x]], r));
    }
    T query(int x, int y) {
        int lca = LCA(x, y);
        return f(f(query_vertical(x, lca), query_vertical(y, lca)), HP[link[lca]].query(h[lca], h[lca] + 1));
    }
};
const int N = 1e5;
vector <vector <int>> g;
int val[N + 5];

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 <int> HLD(g, val + 1, val + n + 1, [](int a, int b){ return max(a, b); }, 0);
    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;
}