Cod sursa(job #3129627)

Utilizator RobertAcAcatrinei Robert-Marian RobertAc Data 15 mai 2023 11:39:02
Problema Heavy Path Decomposition Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.44 kb
#include <bits/stdc++.h>
// #define in cin
// #define out cout

using namespace std;

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

const int nmax = 1e5 + 5e0;
const int lgmax = 17;

int n, m;
int v[nmax];
int depth[nmax];
int pIndex[nmax];
vector<int> adj[nmax];
vector<int> paths;
int aint[3 * nmax];
int aintIndex[nmax];
int parent[nmax];

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

int query(int l, int r, int st = 1, int dr = n, int nod = 1)
{
    if (l == st && r == dr)
    {
        return aint[nod];
    }
    else
    {
        int mid = (st + dr) / 2;
        if (r <= mid)
            return query(l, r, st, mid, 2 * nod);
        else if (mid < l)
            return query(l, r, mid + 1, dr, 2 * nod + 1);
        else
        {
            return max(
                query(l, mid, st, mid, 2 * nod),
                query(mid + 1, r, mid + 1, dr, 2 * nod + 1));
        }
    }
}

int ind = 1;

vector<int> dfs(int nod = 1, int p = 0, int dep = 0)
{
    parent[nod] = p;
    depth[nod] = dep;
    vector<int> path;
    vector<vector<int>> tmm;
    int maxx = 0;
    for (auto i : adj[nod])
    {
        if (i != p)
        {
            auto tm = dfs(i, nod, dep + 1);
            tmm.push_back(tm);
            maxx = max(maxx, (int)tm.size());
        }
    }
    bool found = 0;
    for (auto i : tmm)
    {
        if (i.size() == maxx && found == 0)
        {
            path = i;
            found = 1;
        }
        else
        {
            paths.push_back(i.back());
            for (auto j : i)
            {
                pIndex[j] = paths.size() - 1;
                aintIndex[j] = ind++;
            }
        }
    }
    path.push_back(nod);
    return path;
}

void readInput()
{
    in >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        in >> v[i];
    }
    for (int i = 1; i < n; i++)
    {
        int a, b;
        in >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
}

int q(int x, int y)
{
    int ans = 0;
    while (1)
    {
        auto px = paths[pIndex[x]];
        auto py = paths[pIndex[y]];
        if (px == py)
        {
            if (depth[x] > depth[y])
            {
                swap(x, y);
            }
            ans = max(ans, query(aintIndex[y], aintIndex[x]));
            break;
        }
        else
        {
            if (depth[px] < depth[py])
            {
                swap(x, y);
                swap(px, py);
            }
            ans = max(ans, query(aintIndex[x], aintIndex[px]));
            x = parent[px];
        }
    }
    return ans;
}

void solve()
{
    for (int i = 1; i <= n; i++)
    {
        update(aintIndex[i], v[i]);
    }
    for (int i = 0; i < m; i++)
    {
        int t, x, y;
        in >> t >> x >> y;
        if (t == 0)
        {
            v[x] = y;
            update(aintIndex[x], y);
        }
        else
        {
            out << q(x, y) << '\n';
        }
    }
}

int main()
{
    readInput();
    auto i = dfs();
    paths.push_back(i.back());
    for (auto j : i)
    {
        pIndex[j] = paths.size() - 1;
        aintIndex[j] = ind++;
    }
    solve();
}