Cod sursa(job #2814907)

Utilizator RaresFelixTudose Rares Felix RaresFelix Data 8 decembrie 2021 19:49:48
Problema Heavy Path Decomposition Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.7 kb
#include <bits/stdc++.h>
#define MN 107171
using namespace std;

ifstream fi("heavypath.in");
ofstream fo("heavypath.out");
int n, m, Val[MN];
vector<int> L[MN];

struct AINT {
    int V[3 * MN];
    void build(int u, int s, int d, int* O) {
        if(s == d) {
            V[u] = O[s];
            return;
        }
        build(u * 2, s, (s + d) / 2, O);
        build(u * 2 + 1, (s + d) / 2 + 1, d, O);
        V[u] = max(V[u * 2], V[u * 2 + 1]);
    }

    void update(int p, int v, int u = 1, int s = 1, int d = MN - 1) {
        if(d < p || p < s) return;
        if(s == d) {
            V[u] = v;
            return;
        }
        update(p, v, u * 2, s, (s + d) / 2);
        update(p, v, u * 2 + 1, (s + d) / 2 + 1, d);
        V[u] = max(V[u * 2], V[u * 2 + 1]);
    }

    int query(int l, int r, int u = 1, int s = 1, int d = MN - 1) {
        if(d < l || r < s) return 0;
        if(l <= s && d <= r) return V[u];
        return max(query(l, r, u * 2, s, (s + d) / 2), query(l, r, u * 2 + 1, (s + d) / 2 + 1, d));
    }

};


struct HeavyPath {
    AINT Arbore;
    int Sum[MN], Niv[MN];
    int nrseg, St[MN], Nr[MN], H[MN], Cul[MN]; // AINT
    int PaterFam[MN], Par[MN];

//    int lca(int u, int v) {
//        if(Niv[u] < Niv[v]) swap(u, v);
//        for(int k = 16, d = Niv[u] - Niv[v]; k >= 0; --k)
//            if(d & (1 << k)) u = ST[k][u];
//        if(u == v) return u;
//        for(int k = 16; k >= 0; --k)
//            if(ST[k][u] != ST[k][v]) u = ST[k][u], v = ST[k][v];
//        return ST[0][u];
//    }

    void id_dfs(int u, int p, int niv) {
        Sum[u] = 1;
        Niv[u] = niv;
        for(auto it : L[u]) if (it != p) {
            id_dfs(it, u, niv + 1);
            Sum[u] += Sum[it];
        }
    }

    void cul_dfs(int u, int p, int color, int h) {
        ++Nr[color];
        Cul[u] = color;
        H[u] = h;
        if(!h) PaterFam[color] = u;
        Par[u] = p;

        int ma = 0, sma = -1;
        for(auto it : L[u]) if (it != p && Sum[it] > sma) {
            sma = Sum[it];
            ma = it;
        }
        for(auto it : L[u]) if (it != p) {
            if(it == ma) cul_dfs(it, u, color, h + 1);
            else cul_dfs(it, u, ++nrseg, 0);
        }
    }

    void build() {
        id_dfs(1, 0, 0);
        cul_dfs(1, 0, (nrseg = 1), 0);
        for(int i = 1; i <= nrseg; ++i) {
            St[i] = Nr[i - 1] + 1;
            Nr[i] += Nr[i - 1];
        }
        for(int i = 1; i <= n; ++i) Arbore.update(St[Cul[i]] + H[i], Val[i]);

//        for(int k = 1; k < 17; ++k)
//            for(int i = 1; i <= n; ++i) ST[k][i] = ST[k-1][ST[k-1][i]];
    }

    void update(int p, int v) { Arbore.update(St[Cul[p]] + H[p], v); }

//    int solve(int fiu, int par) {
//        if(Cul[fiu] == Cul[par]) return Arbore.query(St[Cul[par]] + H[par], St[Cul[fiu]] + H[fiu]);
//        else return max(solve(fiu, PaterFam[Cul[fiu]]), solve(ST[0][PaterFam[Cul[fiu]]], par));
//    }

    int query(int u, int v) {
        int re = 0;
        while(1) {
            if(Cul[u] == Cul[v])
                return max(re, Arbore.query(St[Cul[u]] + min(H[u], H[v]), St[Cul[u]] + max(H[u], H[v])));
            if(Niv[PaterFam[Cul[u]]] < Niv[PaterFam[Cul[v]]]) swap(u, v);
            re = max(re, Arbore.query(St[Cul[u]], St[Cul[u]] + H[u]));
            u = Par[PaterFam[Cul[u]]];
        }
        return re;
    }
};

HeavyPath Sol;
int main() {
    fi >> n >> m;
    for(int i = 1; i <= n; ++i) fi >> Val[i];
    for(int i = 1, u, v; i < n; ++i) {
        fi >> u >> v;
        L[u].push_back(v);
        L[v].push_back(u);
    }
    Sol.build();
    for(int i = 1, tip, a, b; i <= m; ++i) {
        fi >> tip >> a >> b;
        if(tip) fo << Sol.query(a, b) << "\n";
        else Sol.update(a, b);
    }
    return 0;
}