Cod sursa(job #2825627)

Utilizator UnknownPercentageBuca Mihnea-Vicentiu UnknownPercentage Data 4 ianuarie 2022 22:24:06
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.88 kb
#include <bits/stdc++.h>

using namespace std;

inline void Open(const string Name) {
    #ifndef ONLINE_JUDGE
        (void)!freopen((Name + ".in").c_str(), "r", stdin);
        (void)!freopen((Name + ".out").c_str(), "w", stdout);
    #endif
}

const int NMX = 100000;

vector <int> Gr[NMX + 1];

int t[4 * NMX + 1], val[NMX + 1], par[NMX + 1], depth[NMX + 1], heavy[NMX + 1], head[NMX + 1], pos[NMX + 1];
int N, Q, Task, x, y, cur_pos;

int dfs(int v) {
    int sz = 1, mx_c_sz = 0;
    for(int c : Gr[v]) {
        if(c != par[v]) {
            par[c] = v, depth[c] = depth[v] + 1;
            int c_sz = dfs(c);
            sz += c_sz;
            if(c_sz > mx_c_sz)
                mx_c_sz = c_sz, heavy[v] = c;
        }
    }

    return sz;
}

void decomp(int v, int h) {
    head[v] = h, pos[v] = ++cur_pos;

    if(heavy[v] != -1)
        decomp(heavy[v], h);

    for(int c : Gr[v])
        if(c != par[v] && c != heavy[v])
            decomp(c, c);
}

void build(int v, int tl, int tr) {
    if(tl == tr) {
        t[v] = val[pos[tl]];
        return;
    }

    int tm = (tl + tr) / 2;
    build(v << 1, tl, tm);
    build(v << 1 | 1, tm + 1, tr);

    t[v] = max(t[v << 1], t[v << 1 | 1]);
}

void update(int v, int tl, int tr, int pos, int new_val) {
    if(tl == tr) {
        t[v] = new_val;
        return;
    }

    int tm = (tl + tr) / 2;
    if(pos <= tm)
        update(v << 1, tl, tm, pos, new_val);
    else 
        update(v << 1 | 1, tm + 1, tr, pos, new_val);

    t[v] = max(t[v << 1], t[v << 1 | 1]);
}

int query(int v, int tl, int tr, int l, int r) {
    if(l > r)
        return INT_MIN;
    if(l == tl && r == tr)
        return t[v];

    int tm = (tl + tr) / 2;
    return max(query(v << 1, tl, tm, l, min(r, tm)), query(v << 1 | 1, tm + 1, tr, max(l, tm + 1), r));
}

int Q_(int a, int b) {
    int res = INT_MIN;
    for(;head[a] != head[b];b = par[head[b]]) {
        if(depth[head[a]] > depth[head[b]])
            swap(a, b);

        res = max(res, query(1, 1, N, pos[head[b]], pos[b]));
    }

    if(depth[a] > depth[b])
        swap(a, b);

    res = max(res, query(1, 1, N, pos[a], pos[b]));
    return res;
}

void solve() {
    cin >> N >> Q;
    for(int i = 1;i <= N;i++)
        cin >> val[i];

    for(int i = 1;i < N;i++) {
        cin >> x >> y;
        Gr[x].emplace_back(y);
        Gr[y].emplace_back(x);
    }

    memset(heavy, -0x1, sizeof(heavy));
    dfs(1);
    decomp(1, 1);

    build(1, 1, N);
    while(Q--) {
        cin >> Task >> x >> y;

        if(Task == 0)
            update(1, 1, N, pos[x], y);
        if(Task == 1)
            cout << Q_(x, y) << "\n";
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    Open("heavypath");

    int T = 1;
    for(;T;T--) {
        solve();
    }

    return 0;
}