Cod sursa(job #2880291)

Utilizator pielevladutPiele Vladut Stefan pielevladut Data 29 martie 2022 16:41:58
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.74 kb
#include <bits/stdc++.h>

using namespace std;

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

const int nmax = 100000;

int n, m, val[nmax + 5];
int nivel[nmax + 5], dim[nmax + 5], tata[nmax + 5], head[nmax + 5];
int pozHeavy[nmax + 5], cnt;
vector<int> g[nmax + 5];

struct AINT
{
    int aint[4 * nmax + 5];

    void build(int nod, int st, int dr)
    {
        if(st == dr)
        {
            aint[nod] = val[pozHeavy[st]];
            return ;
        }
        int mid = (st + dr) >> 1;
        build(2 * nod, st, mid);
        build(2 * nod + 1, mid + 1, dr);
        aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
    }

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

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

};

AINT aint;

void dfs(int fiu, int nod)
{
    nivel[fiu] = 1 + nivel[nod];
    dim[fiu] = 1;
    tata[fiu] = nod;
    for(int i = 0; i != g[fiu].size(); i ++)
    {
        int it = g[fiu][i];
        if(it == nod)
        {
            continue;
        }
        dfs(it, fiu);
        dim[fiu] += dim[it];
    }
}

void dfsHeavy(int fiu, int tata)
{
    pozHeavy[fiu] = ++cnt;
    int maxDist = 0, heavySon;
    for(int i = 0; i != g[fiu].size(); i ++)
    {
        int it = g[fiu][i];
        if(it == tata)
        {
            continue;
        }
        if(dim[it] > maxDist)
        {
            maxDist = dim[it];
            heavySon = it;
        }
    }
    if(maxDist == 0)
    {
        return ;
    }
    head[heavySon] = head[fiu];
    dfsHeavy(heavySon, fiu);
    for(int i = 0; i != g[fiu].size(); i ++)
    {
        int it = g[fiu][i];
        if(it == tata || it == heavySon)
        {
            continue;
        }
        dfsHeavy(it, fiu);
    }
}

int queryHeavy(int x, int y)
{
    int sol = 0;
    if(head[x] == head[y])
    {
        if(nivel[x] > nivel[y])
        {
            swap(x, y);
        }
        sol = aint.query(1, 1, n, pozHeavy[x], pozHeavy[y]);
    }
    else
    {
        if(nivel[head[x]] < nivel[head[y]])
        {
            swap(x, y);
        }
        sol = aint.query(1, 1, n, pozHeavy[head[x]], pozHeavy[x]);
        x = tata[head[x]];
        sol = max(sol, queryHeavy(x, y));
    }
    return sol;
}


int main()
{
    fin >> n >> m;
    for(int i = 1; i <= n; i ++)
    {
        fin >> val[i];
    }
    for(int i = 1; i < n; i ++)
    {
        int u, v;
        fin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    for(int i = 1; i <= n; i ++)
    {
        head[i] = i;
    }
    dfs(1, 0);
    dfsHeavy(1, 0);
    aint.build(1, 1, n);
    while(m--)
    {
        int type;
        fin >> type;
        if(type == 0)
        {
            int nod, valnew;
            fin >> nod >> valnew;
            aint.update(1, 1, n, pozHeavy[nod], valnew);
        }
        else
        {
            int x, y;
            fin >> x >> y;
            fout << queryHeavy(x, y) << '\n';
        }
    }
}