Cod sursa(job #2920852)

Utilizator VladPislaruPislaru Vlad Rares VladPislaru Data 26 august 2022 13:42:52
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.71 kb
#include <bits/stdc++.h>

using namespace std;

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


const int MaxN = 1e5 + 5;

int n, m;
int val[MaxN], sz[MaxN], what_lant[MaxN], nr_lant, poz_lant[MaxN], niv[MaxN], tata_lant[MaxN];

vector <int>  elem_lant[MaxN];
vector < int > adj[MaxN];


void DFS (int nod, int tata) {

    int leaf = 1;
    sz[nod] = 1;
    int heavy_son = 0;
    for (auto i : adj[nod])
        if (i != tata)  {
        leaf = 0;
        niv[i] = niv[nod] + 1;
        DFS(i, nod);
        sz[nod] += sz[i];
        if (!heavy_son || sz[heavy_son] < sz[i])
            heavy_son = i;
    }
    if (leaf) {
        what_lant[nod] = ++nr_lant;
        poz_lant[nod] = 1;
        elem_lant[nr_lant].push_back(0);
        elem_lant[nr_lant].push_back(nod);
        return;
    }

    what_lant[nod] = what_lant[heavy_son];
    elem_lant[what_lant[nod]].push_back(nod);
    poz_lant[nod] = elem_lant[what_lant[nod]].size() - 1;
    for (int i : adj[nod]) {
        if (i != heavy_son && i != tata) {
            tata_lant[what_lant[i]] = nod;
        }
    }
}


vector <vector <int> > aint;

void Build (int nr, int nod, int st, int dr) {


    if (st == dr) {
        aint[nr][nod] = val[elem_lant[nr][st]];
    }
    else {
        int mid = (st + dr ) / 2;
        Build(nr, 2 * nod, st, mid);
        Build(nr, 2 * nod + 1, mid + 1, dr);
        aint[nr][nod] = max (aint[nr][2 * nod], aint[nr][2 * nod + 1]);
    }
}

void Update (int nr, int nod, int st, int dr, int poz, int val) {

    if (st == dr && st == poz)
        aint[nr][nod] = val;
    else {
        int mid = (st + dr) / 2;
        if (poz <= mid)
            Update(nr, 2 * nod, st, mid, poz , val);
        else Update(nr, 2 * nod + 1, mid + 1, dr, poz, val);
        aint[nr][nod] = max(aint[nr][2 * nod], aint[nr][2 * nod + 1]);
    }
}

int Query (int nr, int nod, int st, int dr, int x, int y) {
    if (x <= st && dr <= y) {
        return aint[nr][nod];
    }
    else {
        int mid = (st + dr) / 2;
        int val1 = -2e9, val2 = -2e9;
        if (x <= mid)
            val1 = Query(nr, 2 * nod, st, mid, x, y);
        if (y > mid)
            val2 = Query (nr , 2 * nod + 1, mid + 1, dr, x, y);
        return max(val1, val2);
    }
}


int Solve (int x, int y) {
    if (what_lant[x] == what_lant[y]) {
        return Query(what_lant[x], 1, 1, elem_lant[what_lant[x]].size() - 1, min(poz_lant[y], poz_lant[x]), max(poz_lant[y], poz_lant[x]));
    }

    if (niv[tata_lant[what_lant[x]]] < niv[tata_lant[what_lant[y]]])
        swap(x, y);
    int val1 = Query(what_lant[x], 1, 1, elem_lant[what_lant[x]].size() - 1, 1, poz_lant[x]);
    int val2 = Solve(tata_lant[what_lant[x]], y);

    return max (val1, val2);
}

int main()
{

    fin >> n >> m;
    for (int i = 1; i <= n; i++)
        fin >> val[i];
    for (int i = 1; i < n; i++){
        int x , y;
        fin >> x >> y;
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    tata_lant[1] = 0;
    nr_lant = 1;
    DFS(1, 0);

    aint.resize(nr_lant * 4);
    for (int i = 1; i <= nr_lant; i++) {
       aint[i].resize(30);
       reverse(elem_lant[i].begin() + 1, elem_lant[i].end());
       Build(i, 1, 1, elem_lant[i].size() - 1);
    }

    for (int i = 1; i <= n; i++)
        poz_lant[i] = elem_lant[what_lant[i]].size() - poz_lant[i];
    for (int i = 1; i <= m; i++) {
        int x, y, t;

        fin >> t >> x >> y;
        if (t == 0)
            Update(what_lant[x], 1, 1, elem_lant[what_lant[x]].size() - 1, poz_lant[x], y);
        else {
            int ans = Solve(x, y);
            fout << ans << "\n";
        }
    }
    return 0;
}