Cod sursa(job #3304880)

Utilizator Mihai_OctMihai Octavian Mihai_Oct Data 28 iulie 2025 12:34:28
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.13 kb
#include <bits/stdc++.h>

using namespace std;

#define ST_DIO 0
#if ST_DIO
    #define fin cin
    #define fout cout
#else
    ifstream fin("heavypath.in");
    ofstream fout("heavypath.out");
#endif  // ST_DIO

int n, q, i, val[100002];
vector<int> gr[100002];
int aint[2 * 100002];

int niv[100002];
int tata[100002];
int subArb[100002];
int cap[100002];
int timp[100002];

static inline void UpdateAINT(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) UpdateAINT(nodSt, st, mij, poz, val);
        else           UpdateAINT(nodDr, mij + 1, dr, poz, val);

        aint[nod] = max(aint[nodSt], aint[nodDr]);
    }
}

static inline int QueryAINT(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 = 0, q2 = 0;
        if(qst <= mij) q1 = QueryAINT(nodSt, st     , mij, qst, qdr);
        if(mij <  qdr) q2 = QueryAINT(nodDr, mij + 1, dr , qst, qdr);
        return max(q1, q2);
    }
}

static inline void DFSInit(int nod = 1, int ant = 0) {
    tata[nod] = ant;
    niv[nod] = niv[ant] + 1;
    subArb[nod] = 1;
    for(int urm : gr[nod]) {
        if(urm != ant) {
            DFSInit(urm, nod);
            subArb[nod] += subArb[urm];
        }
    }
}

int timpCur = 0;
static inline void DFSHeavy(int nod, int ant, int capCur) {
    timp[nod] = ++timpCur;
    cap[nod] = capCur;

    int urmCur = 0;
    for(int urm : gr[nod]) {
        if(urm != ant) {
            if(subArb[urmCur] < subArb[urm]) urmCur = urm;
        }
    }
    if(urmCur > 0) DFSHeavy(urmCur, nod, capCur);
    for(int urm : gr[nod]) {
        if(urm != ant && urm != urmCur) {
            DFSHeavy(urm, nod, urm);
        }
    }
}

static inline int QueryHeavy(int st, int dr) {
    int ret = 0;
    while(cap[st] != cap[dr]) {
        int capSt = cap[st];
        int capDr = cap[dr];
        if(niv[capSt] > niv[capDr]) {
            swap(st, dr);
            swap(capSt, capDr);
        }
        ret = max(ret, QueryAINT(1, 1, n, timp[capDr], timp[dr]));
        dr = tata[capDr];
    }

    if(niv[st] > niv[dr]) swap(st, dr);
    ret = max(ret, QueryAINT(1, 1, n, timp[st], timp[dr]));
    return ret;
}

int main() {
    if(ST_DIO) 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);
    }

    DFSInit(1, 0);
    DFSHeavy(1, 0, 1);
    for(i = 1; i <= n; i++) UpdateAINT(1, 1, n, timp[i], val[i]);

    for(i = 1; i <= q; i++) {
        int op, x, y;
        fin >> op >> x >> y;
        if(op == 0) UpdateAINT(1, 1, n, timp[x], y);
        else fout << QueryHeavy(x, y) << "\n";
    }

    return 0;
}