Cod sursa(job #3290705)

Utilizator IleaIlea Bogdan Ilea Data 31 martie 2025 17:18:16
Problema Heavy Path Decomposition Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.51 kb
#include <iostream>
#include <vector>
using namespace std;

#define NMAX 100005
#define def int nod=1, int st=1, int dr=n
#define int size_t

int n, q, x, y, val, sum=0, cp=0;
int sz[NMAX], hchild[NMAX], d[NMAX], aint[4*NMAX], a[NMAX], pr[NMAX], head[NMAX], pos[NMAX];
vector<int> g[NMAX];
void dfs(int r, int p){
    ++sz[r];
    pr[r]=p;
    int maxim=0;
    hchild[r]=-1;
    for (auto it:g[r]){
        if (it==p)continue;
        d[it]=d[r]+1;
        dfs(it, r);
        sz[r]+=sz[it];
        if (maxim<sz[it]){
            maxim=sz[it];
            hchild[r]=it;
        }
    }
}
void update(def){
    if (st==dr){
        aint[nod]=val;
        return;
    }
    int mij=(st+dr)/2;
    if (x<=mij)update(2*nod, st, mij);
    else update(2*nod+1, mij+1, dr);
    aint[nod]=max(aint[2*nod], aint[2*nod+1]);
}
void query(def){
    if (y<st || dr<x)return;
    if (x<=st && dr<=y){
        sum=max(sum, aint[nod]);
        return;
    }
    int mij=(st+dr)/2;
    query(2*nod, st, mij);
    query(2*nod+1, mij+1, dr);
}
void dec_dfs(int r, int p, int h){
    head[r]=h;
    pos[r]=cp++;
    x=pos[r], val=a[r];
    update();
    if (hchild[r]!=-1){
        dec_dfs(hchild[r], r, h);
    }
    for (auto it:g[r]){
        if (it==p || it==hchild[r])continue;
        dec_dfs(it, r, it);
    }
}
void path_query(){
    int i=x, j=y;
    while (head[i]!=head[j]){
        if (d[head[i]]>d[head[j]])swap(i, j);
        x=pos[head[j]], y=pos[j];
        query();
        j=pr[head[j]];
    }
    if (d[i]>d[j])swap(i, j);
    x=pos[i], y=pos[j];
    query();
}
void solve(){
    cin>>n>>q;
    for (int i=1; i<=n; ++i)cin>>a[i];
    for (int i=1; i<n; ++i){
        int x, y;
        cin>>x>>y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    dfs(1, 0);
    dec_dfs(1, 0, 1);
    for (int i=0; i<q; ++i){
        int op;
        cin>>op;
        if (op==0){
            // update
            cin>>x>>val;
            x=pos[x];
            update();
        } else {
            // query
            cin>>x>>y;
            sum=0;
            path_query();
            cout<<sum<<"\n";
        }
    }
}
signed main(){
    #ifdef LOCAL
        freopen("date.in", "r", stdin);
        freopen("date.out", "w", stdout);
    #else
        ios::sync_with_stdio(false);
        cin.tie(NULL);
        cout.tie(NULL);
        freopen("heavypath.in", "r", stdin);
        freopen("heavypath.out", "w", stdout);
    #endif
    solve();
    return 0;
}