Cod sursa(job #3324898)

Utilizator Radu_BicliBiclineru Radu Radu_Bicli Data 23 noiembrie 2025 21:47:21
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.04 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
const int MAXN = 100002;
int n, q, i, tata[MAXN], niv[MAXN], hvy[MAXN], vf[MAXN], tur[MAXN], val[MAXN];
vector<int> gr[MAXN];

namespace AINT {
    int aint[2 * MAXN];

    static inline void Update(int nod, int st, int dr, int poz, int val) {
        if(st == dr) aint[nod] = val;
        else {
            int mij = st + (dr - st) / 2;
            int nodSt = nod + 1;
            int nodDr = nod + 2 * (mij - st + 1);
            if(poz <= mij) Update(nodSt, st, mij, poz, val);
            else           Update(nodDr, mij + 1, dr, poz, val);
            aint[nod] = max(aint[nodSt], aint[nodDr]);
        }
    }

    static inline int Query(int nod, int st, int dr, int qst, int qdr) {
        if(qst <= st && dr <= qdr) return aint[nod];
        else {
            int mij = st + (dr - st) / 2;
            int nodSt = nod + 1;
            int nodDr = nod + 2 * (mij - st + 1);
            int q1 = INT_MIN, q2 = INT_MIN;
            if(qst <= mij) q1 = Query(nodSt, st, mij, qst, qdr);
            if(mij <  qdr) q2 = Query(nodDr, mij + 1, dr, qst, qdr);
            return max(q1, q2);
        }
    }
}

namespace HPD {
    static inline int DFS(int nod = 1) {
        int subArb = 1, subMa = 0;
        for(int urm : gr[nod]){
            if(urm != tata[nod]) {
                tata[urm] = nod;
                niv[urm] = 1 + niv[nod];

                int fii = DFS(urm);
                subArb += fii;

                if(fii > subMa) {
                    subMa = fii;
                    hvy[nod] = urm;
                }
            }
        }
        return subArb;
    }

    int tp = 0;
    static inline void Descomp(int nod = 1, int vfCur = 1) {
        vf[nod] = vfCur;
        tur[nod] = ++tp;
        if(hvy[nod] != 0) Descomp(hvy[nod], vfCur);
        for(int urm : gr[nod]) {
            if(urm != tata[nod] && urm != hvy[nod]) {
                Descomp(urm, urm);
            }
        }
    }

    static inline int Query(int x, int y) {
        int rasp = INT_MIN;
        while(vf[x] != vf[y]) {
            if(niv[vf[x]] > niv[vf[y]]) swap(x, y);
            rasp = max(rasp, AINT::Query(1, 1, n, tur[vf[y]], tur[y]));
            y = tata[vf[y]];
        }

        if(niv[x] > niv[y]) swap(x, y);
        return max(rasp, AINT::Query(1, 1, n, tur[x], tur[y]));
    }
}

int main() {
    //ios_base::sync_with_stdio(false);
    fin.tie(nullptr);
    fout.tie(nullptr);

    fin >> n >> q;
    for(i = 1; i <= n; i++) fin >> val[i];
    for(i = 1; i < n; i++) {
        int x, y;
        fin >> x >> y;
        gr[x].push_back(y);
        gr[y].push_back(x);
    }
    HPD::DFS();
    HPD::Descomp();
    for(i = 1; i <= n; i++) AINT::Update(1, 1, n, tur[i], val[i]);
    while(q--) {
        int op, x, y;
        fin >> op >> x >> y;
        if(op == 0) AINT::Update(1, 1, n, tur[x], y);
        else fout << HPD::Query(x, y) << "\n";
    }

    return 0;
}