Cod sursa(job #2939928)

Utilizator Vlad_AnicaAnica-Popa Vlad-Ioan Vlad_Anica Data 14 noiembrie 2022 14:33:40
Problema Heavy Path Decomposition Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.73 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 1e5 + 1;

vector<int> gr[NMAX];
int vals[NMAX], sb[NMAX], dad[NMAX], depth[NMAX];
int aint[NMAX * 4];
int head[NMAX], pos[NMAX], heavy[NMAX];

int lefts(int nd);
int rights(int nd);
void upd(int nd, int l, int r, int pos, int val);
int query(int nd, int l, int r, int ql, int qr);
void dfs(int nd);
void hld(int nd, int h);
int queryHLD(int u, int v, int n);

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

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

    int u, v;
    for (int i = 1; i < n; i++) {
        fin >> u >> v;
        gr[u].push_back(v);
        gr[v].push_back(u);
    }

    dfs(1);
    hld(1, 1);

    for (int i = 1; i <= n; i++)
        upd(1, 1, n, pos[i], vals[i]);



    for (int i = 1; i <= m; i++) {
        fin >> t >> u >> v;
        if (t == 0)
            upd(1, 1, n, pos[u], v);
        else
            fout << queryHLD(u, v, n) << '\n';
    }
    return 0;
}

int lefts(int nd) {
    return nd << 1;
}

int rights(int nd) {
    return (nd << 1) + 1;
}

void upd(int nd, int l, int r, int pos, int val) {
    if (l == r) {
        aint[nd] = val;
        return;
    }

    int mid = (l + r) >> 1;
    if (pos <= mid)
        upd(lefts(nd), l, mid, pos, val);
    else
        upd(rights(nd), mid + 1, r, pos, val);

    aint[nd] = max(aint[lefts(nd)], aint[rights(nd)]);
}

int query(int nd, int l, int r, int ql, int qr) {
    if (l > qr || r < ql)
        return -1;
    if (l >= ql && r <= qr)
        return aint[nd];

    int mid = (l + r) >> 1;

    return max(query(lefts(nd), l, mid, ql, qr), query(rights(nd), mid + 1, r, ql, qr));
}

void dfs(int nd) {
    sb[nd] = 1;
    int mx = 0;
    for (int nxt: gr[nd]) {
        if (nxt != dad[nd]) {
            dad[nxt] = nd;
            depth[nxt] = depth[nd] + 1;
            dfs(nxt);
            if (mx < sb[nxt]) {
                mx = sb[nd];
                heavy[nd] = nxt;
            }
            sb[nd] += sb[nxt];
        }
    }
}
int cpos = 1;
void hld(int nd, int h) {
    head[nd] = h, pos[nd] = cpos++;

    if (heavy[nd])
        hld(heavy[nd], h);

    for (int nxt: gr[nd])
        if (nxt != dad[nd] && nxt != heavy[nd])
            hld(nxt, nxt);
}
int queryHLD(int u, int v, int n) {
    int res = 0;
    for (; head[u] != head[v]; v = dad[head[v]]) {
        if (depth[head[u]] > depth[head[v]])
            swap(u, v);
        res = max(res, query(1, 1, n, pos[head[v]], pos[v]));
    }

    if (depth[u] > depth[v])
        swap(u, v);


    res = max(res, query(1, 1, n, pos[u], pos[v]));
    return res;
}