Cod sursa(job #2382911)

Utilizator Constantin.Dragancea Constantin Constantin. Data 18 martie 2019 19:54:48
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.74 kb
#include <bits/stdc++.h>
using namespace std;

#define L (nod << 1)
#define R (L | 1)
const int N = 100010;
int n, m, k, a[N], p[N], sz[N], nrlant = 1, arb[4*N], cnt[N], lvl[N], lnt[N], ord[N], bgn[N];
vector <int> v[N];

void update(int nod, int st, int dr, int idx, int val){
    if (st == dr){
        arb[nod] = val;
        return;
    }
    int mid = (st + dr) >> 1;
    if (idx <= mid) update(L, st, mid, idx, val);
    else update(R, mid + 1, dr, idx, val);
    arb[nod] = max(arb[L], arb[R]);
}

int query(int nod, int st, int dr, int l, int r){
    if (st >= l && dr <= r) return arb[nod];
    int mid = (st + dr) >> 1;
    int left = -1, right = -1;
    if (l <= mid) left = query(L, st, mid, l, r);
    if (r > mid) right = query(R, mid + 1, dr, l, r);
    return max(left, right);
}

int dfs(int q, int pr){
    sz[q] = 1;
    for(auto it: v[q])
        if (it != pr) sz[q] += dfs(it, q);
    return sz[q];
}

void hld(int q, int pr, int depth){
    lnt[q] = nrlant;
    ord[q] = ++cnt[nrlant];
    lvl[lnt[q]] = depth;
    //cout << q << " " << lnt[q] << "\n";
    int mx = -1, mxidx = -1;
    for (auto it: v[q])
        if (it != pr && sz[it] > mx) mx = sz[it], mxidx = it;
    if (mxidx != -1) hld(mxidx, q, depth);
    for (auto it: v[q])
        if (it != pr && it != mxidx)
            p[++nrlant] = q, hld(it, q, depth+1);
    if (ord[q] == cnt[lnt[q]]) bgn[lnt[q]] = k + 1, k += cnt[lnt[q]];
    update(1, 1, n, bgn[lnt[q]] + ord[q] - 1, a[q]);
}

int main(){
    ifstream cin ("heavypath.in");
    ofstream cout ("heavypath.out");
    cin >> n >> m;
    for (int i=1; i<=n; i++) cin >> a[i];
    for (int i=1, x, y; i<n; i++){
        cin >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1, -1);
    hld(1, -1, 1);
    //for (int i=1; i<=n; i++) cout << i << ": " << lnt[i] << " " << bgn[lnt[i]] << '\n';
    for (int i=1, o, x, y; i<=m; i++){
        cin >> o >> x >> y;
        if (!o) update(1, 1, n, bgn[lnt[x]] + ord[x]-1, y);
        else{
            int rs = -1;
            if (lvl[lnt[x]] > lvl[lnt[y]]) swap(x, y);
            while (lvl[lnt[y]] > lvl[lnt[x]]){
                rs = max(rs, query(1, 1, n, bgn[lnt[y]], ord[y] + bgn[lnt[y]]-1));
                y = p[lnt[y]];
            }
            while (lnt[y] != lnt[x]){
                rs = max(rs, query(1, 1, n, bgn[lnt[y]], bgn[lnt[y]] + ord[y]-1));
                rs = max(rs, query(1, 1, n, bgn[lnt[x]], bgn[lnt[x]] + ord[x]-1));
                y = p[lnt[y]]; x = p[lnt[x]];
            }
            if (ord[x] > ord[y]) swap(x, y);
            rs = max(rs, query(1, 1, n, bgn[lnt[x]] + ord[x]-1, bgn[lnt[x]]+ord[y]-1));
            cout << rs << "\n";
        }
    }
    return 0;
}