Cod sursa(job #2901068)

Utilizator Andrei-27Arhire Andrei Andrei-27 Data 12 mai 2022 20:42:09
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.36 kb
#include <bits/stdc++.h>

using namespace std;

const long long NR = 2e5 + 1;
const int oo = 1e9;
int d[NR], parent[NR], lvl[NR], aIntPos[NR];
int n, m, aIntCounter = -1;
int rmq[20][NR], weight[NR], aIntChain[NR];
vector<int> v[NR], aInt[NR];

void dfs(int nod, int prt) {
    parent[nod] = prt;
    lvl[nod] = 1 + lvl[prt];
    weight[nod] = 1;
    int heaviest = -1, bestWeight = -1;
    for (auto it : v[nod]) {
        if (it == prt) {
            continue;
        }
        dfs(it, nod);
        weight[nod] += weight[it];
        if (weight[it] > bestWeight) {
            bestWeight = weight[it];
            heaviest = it;
        }
    }
    if (heaviest == -1) {
        ++aIntCounter;
        aInt[aIntCounter].emplace_back(nod);
        aIntPos[nod] = (int) aInt[aIntCounter].size() - 1;
        aIntChain[nod] = aIntCounter;
    } else {
        aInt[aIntChain[heaviest]].emplace_back(nod);
        aIntPos[nod] = (int) aInt[aIntChain[heaviest]].size() - 1;
        aIntChain[nod] = aIntChain[heaviest];
    }
}

int getMax(int chain, int st, int dr) {
    int maxi = d[aInt[chain][st]];
    for (int i = st + 1; i <= dr; ++i) {
        maxi = max(maxi, d[aInt[chain][i]]);
    }
    return maxi;
}

int findMaximum(int x, int y) {
    int maximum = -oo;
    while (aIntChain[x] != aIntChain[y]) {
        if (lvl[parent[aInt[aIntChain[y]].back()]] > lvl[parent[aInt[aIntChain[x]].back()]]) {
            swap(x, y);
        }
        maximum = max(maximum, getMax(aIntChain[x], aIntPos[x], (int) aInt[aIntChain[x]].size() - 1));
        x = parent[aInt[aIntChain[x]].back()];
    }
    return max(maximum, getMax(aIntChain[x], min(aIntPos[x], aIntPos[y]), max(aIntPos[x], aIntPos[y])));
}

signed main() {
    ifstream in("heavypath.in");
    ofstream out("heavypath.out");
    ios::sync_with_stdio(false);
    in.tie();
    int x, y, t;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        cin >> d[i];
    }
    for (int i = 1; i < n; ++i) {
        cin >> x >> y;
        v[x].emplace_back(y);
        v[y].emplace_back(x);
    }
    dfs(1, 0);
    for (int i = 1; i <= m; ++i) {
        cin >> t >> x >> y;
        if (t == 0) {
            d[x] = y;
        } else {
            out << findMaximum(x, y) << '\n';
            //cout << min(findMinimum(x, lca), findMaximum(y, lca)) << '\n';
            //cout << res << '\n';
        }
    }
    in.close();
    out.close();
    return 0;
}