Cod sursa(job #3329672)

Utilizator SkibidiCezarCezar Bolba SkibidiCezar Data 14 decembrie 2025 21:04:19
Problema Heavy Path Decomposition Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.08 kb
#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back

using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");
int n, m, x, y, t, nr, ianstefancazacu;
vector <int> v[100005];
int a[100005];
struct noddeaint{
    int s, d, v;
};
noddeaint aux;
struct lant{
    vector <int> d;
    int pnod, nr;
    vector <noddeaint> aint;
};
pair <int, int> pl[100005];
bool viz[100005];
lant l[100005];
int deep[100005];
int rmq[100005][18];
void dfs(int nod){
    viz[nod] = 1;
    //cout << nod << " " << deep[nod] << "\n";
    if((v[nod].size() == 1 && nod != 1) || v[nod].size() == 0){
        nr++;
        l[nr].d.pb(nod);
        l[nr].aint.pb(aux);
        pl[nod].f = nr;
        pl[nod].s = 0;
    }
    else{
        int maxim = 0, pmax, cop;
        for(int i = 0; i < v[nod].size(); i++){
            cop = v[nod][i];
            if(viz[cop] == 0){
                deep[cop] = deep[nod] + 1;
                dfs(cop);
                rmq[cop][0] = nod;
                if(l[pl[cop].f].d.size() > maxim){
                    maxim = l[pl[cop].f].d.size();
                    pmax = cop;
                }
            }
        }
        l[pl[pmax].f].d.pb(nod);
        pl[nod].f = pl[pmax].f;
        pl[nod].s = pl[pmax].s + 1;
        for(int i = 0; i < v[nod].size(); i++){
            cop = v[nod][i];
            if(cop != pmax){
                l[pl[cop].f].pnod = nod;
            }
        }
    }
}
void build(int p, int ind){
    int st = l[ind].aint[p].s, dr = l[ind].aint[p].d;
    if(st == dr){
        if(st < l[ind].d.size()){
            l[ind].aint[p].v = a[l[ind].d[st]];
        }
        else{
            l[ind].aint[p].v = 0;
        }
    }
    else{
        l[ind].aint[p*2].s = st;
        l[ind].aint[p*2].d = (st + dr) / 2;
        l[ind].aint[p*2+1].s = (st + dr) / 2 + 1;
        l[ind].aint[p*2+1].d = dr;
        build(p * 2, ind);
        build(p * 2 + 1, ind);
        l[ind].aint[p].v = max(l[ind].aint[p*2].v, l[ind].aint[p*2+1].v);
    }
    //cout << ind << " " << p << " " << st << " " << dr << " " << l[ind].aint[p].v << "\n";
}
void upd(int ind, int p, int poz, int u){
    int st = l[ind].aint[p].s, dr = l[ind].aint[p].d;
    if(st <= poz && dr >= poz){
        if(st == dr){
            l[ind].aint[p].v = u;
        }
        else{
            upd(ind, p * 2, poz, u);
            upd(ind, p * 2 + 1, poz, u);
            l[ind].aint[p].v = max(l[ind].aint[p*2].v, l[ind].aint[p*2+1].v);
        }
    }
}
int query(int ind, int p, int s, int d){
    int st = l[ind].aint[p].s, dr = l[ind].aint[p].d;
    if(st >= s && dr <= d){
        return l[ind].aint[p].v;
    }
    else if(dr < s || st > d){
        return -1;
    }
    else{
        return max(query(ind, p * 2, s, d), query(ind, p * 2 + 1, s, d));
    }
}
void niggers(){
    for(int i = 1; i <= 16; i++){
        for(int j = 1; j <= n; j++){
            rmq[j][i] = rmq[rmq[j][i-1]][i-1];
            //cout << i << " " << j << " " << rmq[j][i] << "\n";
        }
    }
}
int queryrmq(int nod, int depth){
    //cout << nod << " ";
    if(deep[nod] == depth){
        return nod;
    }
    else{
        int p = 0;
        while(deep[rmq[nod][p+1]] >= depth){
            p++;
        }
        return queryrmq(rmq[nod][p], depth);
    }
}
int lca(int u, int v){
    int st = 1;
    int dr = min(deep[u], deep[v]);
    int mij, rez;
    while(st <= dr){
        mij = (st + dr) / 2;
        //cout << mij << " ";
        if(queryrmq(u, mij) == queryrmq(v, mij)){
            rez = mij;
            st = mij + 1;
        }
        else{
            dr = mij - 1;
        }
    }
    return queryrmq(u, rez);
}
int queryreal(int nod, int unde){
    //cout << nod << " ";
    if(pl[nod].f == pl[unde].f){
        return query(pl[nod].f, 1, pl[nod].s, pl[unde].s);
    }
    else{
        return max(query(pl[nod].f, 1, pl[nod].s, l[pl[nod].f].d.size() - 1), queryreal(l[pl[nod].f].pnod, unde));
    }
}
void solve(){
    fin >> n >> m;
    for(int i = 1; i <= n; i++){
        fin >> a[i];
    }
    for(int i = 1; i < n; i++){
        fin >> x >> y;
        v[x].pb(y);
        v[y].pb(x);
    }
    deep[1] = 1;
    dfs(1);
    for(int i = 1; i <= nr; i++){
        l[i].nr = 1;
        for(int j = 0; j < l[i].d.size(); j++){
            //cout << l[i].d[j] << " ";
        }
        while(l[i].nr < l[i].d.size()){
            l[i].nr *= 2;
        }
        //cout << "\n" << l[i].nr << "\n";
        l[i].aint.resize(l[i].nr * 2);
        l[i].aint[1].s = 0;
        l[i].aint[1].d = l[i].nr - 1;
        build(1, i);
    }
    niggers();
    while(m--){
        fin >> t >> x >> y;
        if(t == 0){
            upd(pl[x].f, 1, pl[x].s, y);
        }
        else{
            ianstefancazacu = lca(x, y);
            //cout << ianstefancazacu << "\n";
            fout << max(queryreal(x, ianstefancazacu), queryreal(y, ianstefancazacu)) << "\n";
            //cout << "\n";
        }
    }
}

int main()
{
    solve();
    return 0;
}