Cod sursa(job #2871666)

Utilizator florinrafiliuRafiliu Florin florinrafiliu Data 15 martie 2022 13:17:48
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.12 kb
#include <bits/stdc++.h>

using namespace std;

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

const int maxN = 1e5 + 5;
const int INF = 2e9;

int parent[maxN], siz[maxN], level[maxN], v[maxN], ind[maxN], head[maxN];
int arb[4 * maxN];

vector <int> g[maxN];
vector <int> subTree[maxN];
vector <int> dfsOrder;

void compute (int node, int dad = 0) {
    parent[node] = dad;
    siz[node] = 1;
    level[node] = level[dad] + 1;

    for(int to : g[node])
        if(to != dad) {
            compute(to, node);

            subTree[node].push_back(to);
            siz[node] += siz[to];
        }
}

void heavyDfs(int node) {

    dfsOrder.push_back(node);
    ind[node] = int(dfsOrder.size());

    if(subTree[node].size() == 0)
        return ;

    int heavySon = *(subTree[node].begin());

    for(int to : subTree[node])
        if(siz[heavySon] < siz[to]) {
            heavySon = to;
        }

    head[heavySon] = head[node];
    heavyDfs(heavySon);

    for(int to : subTree[node])
        if(to != heavySon)
            heavyDfs(to);
}

void update (int pos, int val, int k, int st, int dr) {
    if(st > dr) return;

    if(st == dr && st == pos) {
        arb[k] = val;
        return;
    }

    int mij = (st + dr) / 2;

    if(pos <= mij)
        update (pos, val, k * 2, st, mij);
    else
        update (pos, val, k*2+1, mij+1, dr);

    arb[k] = max(arb[k*2], arb[k*2+1]);
}

int query (int l, int r, int k, int st, int dr) {
    if(l > r) return -INF;

    if(l <= st && dr <= r) {
        return arb[k];
    }

    int mij = (st + dr) / 2;

    return max(query(l, min(mij, r), k*2, st, mij),
               query(max(l, mij+1), r, k*2+1, mij+1, dr));
}

int Query(int u, int v, int n) {

    if(head[u] == head[v]) { // daca fac parte din acelasi
        if(ind[u] > ind[v])  // lant tare
            swap(u, v);

        return query(ind[u], ind[v], 1, 1, n);
    }

    int ans = 0;
    if(level[parent[head[u]]] > level[parent[head[v]]]) {

        int l = min(ind[u], ind[head[u]]);
        int r = max(ind[u], ind[head[u]]);
        ans = query(l, r, 1, 1, n);

        u = parent[head[u]];
    } else {

        int l = min(ind[v], ind[head[v]]);
        int r = max(ind[v], ind[head[v]]);
        ans = query(l, r, 1, 1, n);

        v = parent[head[v]];
    }

    return max(ans, Query(u, v, n));
}

int main() {
    int n, m; fin >> n >> m;

    for(int i = 1; i <= n; ++i)
        fin >> v[i];

    for(int i = 1; i < n; ++i) {
        int u, v; fin >> u >> v;

        g[u].push_back(v);
        g[v].push_back(u);
    }

    compute(1);

    for(int i = 1; i <= n; ++i)
        head[i] = i;

    heavyDfs(1);

    for(int i = 1; i <= n; ++i)
        update(ind[i], v[i], 1, 1, n);

    for(int i = 1; i <= m; ++i) {
        int op; fin >> op;

        if(op == 0) {
            int pos, val; fin >> pos >> val;
            update(ind[pos], val, 1, 1, n);
        } else {
            int l, r; fin >> l >> r;

            fout << Query(l, r, n) << "\n";
        }
    }

    return 0;
}