Cod sursa(job #3300595)

Utilizator Octa-pe-infoNechifor Octavian Octa-pe-info Data 17 iunie 2025 17:57:17
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.65 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;

ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

vector<int> aint, lant, l_niv, niv, d_lant, a, p_lant, w;
vector<vector<int>> tabel, ll;
vector<bool> viz;

int cnt = 0;

void dfs(int nod,int pr){
    int fr=1, mx=-1;
    viz[nod] = true;
    w[nod] = 1;
    for(auto i : tabel[nod]){
        if(i==pr) continue;
        niv[i] = niv[nod]+1;
        fr = 0;
        dfs(i,nod);
        w[nod] += w[i];
        if(mx==-1 || w[i] > w[mx]) mx = i;
    }
    if(fr){
        lant[nod] = ++cnt;
        ll[cnt].push_back(nod);
    } else {
        ll[lant[mx]].push_back(nod);
        lant[nod] = lant[mx];
        for(auto i : tabel[nod]){
            if(i==mx || i==pr) continue;
            p_lant[lant[i]] = nod;
            l_niv[lant[i]] = niv[nod];
        }
    }
}

void build(int nod,int st,int dr,int decalaj,int id){
    if(st==dr){
        aint[nod + decalaj] = a[ ll[id][st-1] ];
        return;
    }
    int md=(st+dr)/2;
    build(2*nod,st,md,decalaj,id);
    build(2*nod+1,md+1,dr,decalaj,id);
    aint[nod+decalaj] = max(aint[2*nod+decalaj], aint[2*nod+1+decalaj]);
}

void update(int nod,int st,int dr,int target,int v,int decalaj){
    if(st==dr){
        aint[nod+decalaj] = v;
        return;
    }
    int md=(st+dr)/2;
    if(target<=md) update(2*nod,st,md,target,v,decalaj);
    else         update(2*nod+1,md+1,dr,target,v,decalaj);
    aint[nod+decalaj] = max(aint[2*nod+decalaj], aint[2*nod+1+decalaj]);
}

int qeu(int nod,int st,int dr,int l,int r,int decalaj){
    if(st>r || dr<l) return INT_MIN;
    if(l<=st && dr<=r) return aint[nod+decalaj];
    int md=(st+dr)/2;
    return max(
        qeu(2*nod,st,md,l,r,decalaj),
        qeu(2*nod+1,md+1,dr,l,r,decalaj)
    );
}

void bbuild(){
    niv[1]=1;
    dfs(1,0);

    for(int i=1;i<=cnt;i++){
        reverse(ll[i].begin(), ll[i].end());
        if(i>1)
            d_lant[i] = d_lant[i-1] + int(ll[i-1].size())*4;
        build(1,1,int(ll[i].size()), d_lant[i], i);
    }
}

void raspunde(){
    int t,x,y;
    fin >> t >> x >> y;
    if(t==0){

        update(1, 1, int(ll[lant[x]].size()),
               niv[x] - l_niv[lant[x]], y,
               d_lant[lant[x]]);
    } else {

        int rez = INT_MIN;
        while(true){
            if(lant[x]==lant[y]){
                if(niv[x]>niv[y]) swap(x,y);
                rez = max(rez,
                    qeu(1,1,int(ll[lant[x]].size()),
                        niv[x]-l_niv[lant[x]],
                        niv[y]-l_niv[lant[y]],
                        d_lant[lant[x]]));
                break;
            }
            if(l_niv[lant[x]] < l_niv[lant[y]])
                swap(x,y);

            rez = max(rez,
                qeu(1,1,int(ll[lant[x]].size()),
                    1,
                    niv[x]-l_niv[lant[x]],
                    d_lant[lant[x]]));
            x = p_lant[lant[x]];
        }
        fout << rez << "\n";
    }
}

int main(){
    int N, M;
    fin >> N >> M;

    a.resize(N+1);
    tabel.assign(N+1,{});
    viz.assign(N+1,false);
    w.assign(N+1,0);
    lant.assign(N+1,0);
    niv.assign(N+1,0);
    l_niv.assign(N+1,0);
    p_lant.assign(N+1,0);
    d_lant.assign(N+1,0);
    ll.assign(N+1,{});
    aint.assign(4*N + 5, 0);

    for(int i=1;i<=N;i++)
        fin >> a[i];

    for(int i=1,u,v;i<N;i++){
        fin >> u >> v;
        tabel[u].push_back(v);
        tabel[v].push_back(u);
    }

    bbuild();

    for(int i=0;i<M;i++)
        raspunde();

    return 0;
}