Cod sursa(job #3144320)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 7 august 2023 13:09:00
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.01 kb
/// Preset de infoarena
#include <fstream>
#include <iostream>
#include <vector>

using namespace std;

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

const int maxN = 200005;
int n, q, val[maxN];
int sz[maxN], p[maxN], cnt, ind[maxN], depth[maxN], cap[maxN], aint[4 * maxN], v[maxN];
vector <int> G[maxN];

void dfs(int nod, int tata)
{
    p[nod] = tata;
    depth[nod] = depth[tata] + 1;
    sz[nod] = 1;
    cap[nod] = nod;
    for(int vecin : G[nod])
    {
        if(vecin == tata)
            continue;
        dfs(vecin, nod);
        sz[nod] += sz[vecin];
    }
}

void dfs_heavy(int nod)
{
    ind[nod] = ++cnt;
    int max_sz = -1, nxt = -1;
    for(int vecin : G[nod])
    {
        if(vecin == p[nod])
            continue;
        if(sz[vecin] > max_sz)
        {
            max_sz = sz[vecin];
            nxt = vecin;
        }
    }
    if(nxt == -1)
        return;
    cap[nxt] = cap[nod];
    dfs_heavy(nxt);
    for(int vecin : G[nod])
        if(vecin != p[nod] && vecin != nxt)
            dfs_heavy(vecin);
}

void init_aint(int nod, int st, int dr)
{
    if(st == dr)
    {
        aint[nod] = v[st];
        return;
    }
    int med = (st + dr) / 2;
    init_aint(2 * nod, st, med);
    init_aint(2 * nod + 1, med + 1, dr);
    aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
}

void update(int nod, int st, int dr, int upoz, int uval)
{
    if(st == dr)
    {
        aint[nod] = uval;
        return;
    }
    int med = (st + dr) / 2;
    if(upoz <= med)
        update(2 * nod, st, med, upoz, uval);
    if(med + 1 <= upoz)
        update(2 * nod + 1, med + 1, dr, upoz, uval);
    aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
}

int query(int nod, int st, int dr, int qst, int qdr)
{
    if(qst <= st && dr <= qdr)
        return aint[nod];
    int med = (st + dr) / 2, aux = -1;
    if(qst <= med)
        aux = max(aux, query(2 * nod, st, med, qst, qdr));
    if(med + 1 <= qdr)
        aux = max(aux, query(2 * nod + 1, med + 1, dr, qst, qdr));
    return aux;
}

int get_ans(int a, int b)
{
    if(cap[a] == cap[b])
    {
        if(ind[a] > ind[b])
            swap(a, b);
        return query(1, 1, n, ind[a], ind[b]);
    }
    if(depth[cap[a]] < depth[cap[b]])
        swap(a, b);
    return max(query(1, 1, n, ind[cap[a]], ind[a]), get_ans(p[cap[a]], b));
}

int main()
{
    fin >> n >> q;
    for(int i = 1; i <= n; i++)
        fin >> val[i];
    for(int i = 1; i < n; i++)
    {
        int x, y;
        fin >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    dfs(1, 0);
    dfs_heavy(1);
    for(int i = 1; i <= n; i++)
        v[ind[i]] = val[i];
    init_aint(1, 1, n);
    for(int i = 1; i <= q; i++)
    {
        int op, x, y;
        fin >> op >> x >> y;
        if(op == 0)
            update(1, 1, n, ind[x], y);
        if(op == 1)
        {
            int ans = get_ans(x, y);
            fout << ans << '\n';
        }
    }
    return 0;