Cod sursa(job #2684969)

Utilizator giotoPopescu Ioan gioto Data 15 decembrie 2020 13:50:47
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.18 kb
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;

vector <int> v[N];
vector <int> lant[N];
vector <int> Arb[N];

int n, m, nrl;
int wlant[N], val[N], s[N], TT[N], H[N], TT_lant[N], pos[N];

inline void dfs(int nod, int niv){
    H[nod] = niv;
    bool frunza = 1;
    int Max = 0, w = 0;
    for(auto it : v[nod]){
        if(it == TT[nod]) continue ;
        frunza = 0;
        TT[it] = nod;
        dfs(it, niv + 1);
        s[nod] += s[it];
        if(s[it] > Max) Max = s[it], w = it;
    }

    if(frunza){ ///cazul cand e frunza
        s[nod] = 1;
        wlant[nod] = ++nrl;
        lant[nrl].push_back(nod);
        return ;
    }

    ///cazul cand nu e frunza
    int wl = 0;
    wlant[nod] = wl = wlant[w];
    lant[wl].push_back(nod);

    for(auto it : v[nod]){
        if(it == TT[nod]) continue ;
        TT_lant[it] = wl;
    }
}

void build(int i, int st, int dr, int nod){
    if(st == dr){
        Arb[i][nod] = val[lant[i][st - 1]];
        return ;
    }

    int mij = (st + dr) / 2;
    build(i, st, mij, nod * 2);
    build(i, mij + 1, dr, nod * 2 + 1);
    Arb[i][nod] = max(Arb[i][nod * 2], Arb[i][nod * 2 + 1]);
}

void update(int i, int st, int dr, int nod, int x, int y){
    if(st == dr){
        Arb[i][nod] = y;
        return ;
    }

    int mij = (st + dr) / 2;
    if(x <= mij) update(i, st, mij, nod * 2, x, y);
    else update(i, mij + 1, dr, nod * 2 + 1, x, y);
    Arb[i][nod] = max(Arb[i][nod * 2], Arb[i][nod * 2 + 1]);
}

int query(int i, int st, int dr, int nod, int x, int y){
    if(x <= st && dr <= y) return Arb[i][nod];

    int mij = (st + dr) / 2, Sol = 0;
    if(x <= mij) Sol = query(i, st, mij, nod * 2, x, y);
    if(mij + 1 <= y) Sol = max(Sol, query(i, mij + 1, dr, nod * 2 + 1, x, y));

    return Sol;
}

int ans(int x, int y){
    int Sol = 0;
    while(1){
        int lx = wlant[x], ly = wlant[y];

        if(lx == ly){
            int st = min(pos[x], pos[y]);
            int dr = max(pos[x], pos[y]);
            Sol = max(Sol, query(lx, 1, lant[lx].size(), 1, st, dr));
            break ;
        }

        if(H[lant[lx][0]] < H[lant[ly][0]]) swap(x, y), swap(lx, ly);

        Sol = max(Sol, query(lx, 1, lant[lx].size(), 1, 1, pos[x]));
        x = lant[lx][0];
        x = TT[x];
    }
    return Sol;
}

int main()
{
    freopen("heavypath.in", "r", stdin);
    freopen("heavypath.out", "w", stdout);

    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n ; ++i) scanf("%d", &val[i]);

    int x, y;
    for(int i = 1; i < n ; ++i){
        scanf("%d%d", &x, &y);
        v[x].push_back(y);
        v[y].push_back(x);
    }

    dfs(1, 0);

    for(int i = 1; i <= nrl ; ++i){
        reverse(lant[i].begin(), lant[i].end());
        Arb[i].resize(lant[i].size() * 4 + 5);
        build(i, 1, lant[i].size(), 1);
        int NR = 0;
        for(int it : lant[i])
            pos[it] = ++NR;
    }



    int tip;
    for(int i = 1; i <= m ; ++i){
        scanf("%d%d%d", &tip, &x, &y);

        if(tip == 0) update(wlant[x], 1, lant[wlant[x]].size(), 1, pos[x], y);
        else printf("%d\n", ans(x, y));
    }

    return 0;
}