Cod sursa(job #2193489)

Utilizator theodor.moroianuTheodor Moroianu theodor.moroianu Data 10 aprilie 2018 12:59:00
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.15 kb
#include <bits/stdc++.h>
using namespace std;

const int NMAX = 100010;

class Aint
{
    vector <int> aint;
    int n, val, poz, l, r;

    void update(int nod, int st, int dr) {
        if (st > poz || dr < poz)
            return;
        aint[nod] = val;
        if (st != dr) {
            update(2 * nod, st, (st + dr) / 2);
            update(2 * nod + 1, (st + dr) / 2 + 1, dr);
            aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
        }
    }
    int query(int nod, int st, int dr) {
        if (st > r || dr < l)
            return 0;
        if (l <= st && r >= dr)
            return aint[nod];
        return max(query(2 * nod, st, (st + dr) / 2),
                   query(2 * nod + 1, (st + dr) / 2 + 1, dr));
    }
  public:
    Aint(int n) : n(n), aint(vector <int> (4 * n)) { }
    int query(int st, int dr) {
        l = st, r = dr;
        return query(1, 1, n);
    }
    void update(int p, int v) {
        poz = p, val = v;
        update(1, 1, n);
    }
};

struct HeavyPath {
    vector <int> adia[NMAX];
    int h[NMAX], tata[NMAX], jump[NMAX], g[NMAX];
    int id[NMAX], cnt = 0;

    int calc_g(int nod) {
        g[nod] = 1;
        if (tata[nod])
            adia[nod].erase(find(adia[nod].begin(), adia[nod].end(), tata[nod]));
        for (auto i : adia[nod]) {
            tata[i] = nod, h[i] = 1 + h[nod];
            g[nod] += calc_g(i);
        }
        return g[nod];
    }
    void calc_jump(int nod, int jmp) {
        jump[nod] = jmp;
        id[nod] = ++cnt;
        if (adia[nod].empty())
            return;
        pair <int, int> best = { -1, -1 };
        for (auto i : adia[nod])
            best = max(best, { g[i], i });

        calc_jump(best.second, jmp);

        for (auto i : adia[nod])
            if (i != best.second)
                calc_jump(i, i);
    }

    vector <pair <int, int>> get_intervs(int a, int b)
    {
        vector <pair <int, int>> ans;
        while (jump[a] != jump[b]) {
            if (h[jump[a]] < h[jump[b]])
                swap(a, b);
            ans.push_back({ id[jump[a]], id[a] });
            a = tata[jump[a]];
        }
        if (h[a] < h[b])
            swap(a, b);
        ans.push_back({ id[b], id[a] });
        return ans;
    }
};


int v[NMAX];

int main()
{
    ifstream in("heavypath.in");
    ofstream out("heavypath.out");

    int n, m, a, b;
    in >> n >> m;

    HeavyPath hp;
    Aint aint(n + 1);

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

    for (int i(1); i < n; i++) {
        in >> a >> b;
        hp.adia[a].push_back(b);
        hp.adia[b].push_back(a);
    }

    hp.calc_g(1);
    hp.calc_jump(1, 1);

    for (int i(1); i <= n; i++)
        aint.update(hp.id[i], v[i]);

    while (m--) {
        int t;
        in >> t >> a >> b;

        if (t == 1) {
            auto x = hp.get_intervs(a, b);
            int best(0);
            for (auto i : x)
                best = max(best, aint.query(i.first, i.second));
            out << best << '\n';
        }
        else {
            aint.update(hp.id[a], b);
        }
    }
    return 0;
}