Cod sursa(job #3231878)

Utilizator Alex_BerbescuBerbescu Alexandru Alex_Berbescu Data 27 mai 2024 23:39:01
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.26 kb
#pragma GCC optimize("O3")
#pragma GCC optimize("fast-math")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
const int dim = 1e5 + 5;
int n, v[dim], aint[4 * dim + 55], queries, x, y, op, nod_height[dim], tata[dim], sz[dim], pozu[dim], pozudoi[dim], z, idx, maxi, arb[dim];
vector<int>noduri[dim];
void dfs(int nod, int tat = 0)
{
   tata[nod] = tat;
   sz[nod] = 1;
   nod_height[nod] = nod_height[tat] + 1;
   for(auto it: noduri[nod])
   {
       if(it != tat)
       {
            dfs(it, nod);
           sz[nod] += sz[it];
       }
   }
}
void dfsdoi(int nod)
{
    maxi = idx = 0;
    pozu[nod] = ++z;
    pozudoi[z] = nod;
    for(auto it : noduri[nod])
    {
        if(it != tata[nod] && sz[it] > maxi)
        {
            maxi = sz[it];
            idx = it;
        }
    }
    if(idx == 0)
    {
        return;
    }
    arb[idx] = arb[nod];
    dfsdoi(idx);
    for(auto it: noduri[nod])
    {
        if(it != tata[nod] && it != idx)
        {
            arb[it] = it;
            dfsdoi(it);
        }
    }
}
void build(int nod, int st, int dr)
{
    if(st == dr)
    {
        aint[nod] = v[pozudoi[st]];
        return;
    }
    else
    {
        int mid = (st + dr) / 2;
        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;
    }
    else
    {
        int mid = (st + dr) / 2;
        if(poz <= mid)
        {
            update(2 * nod, st, mid, poz, val);
        }
        else
        {
            update(2 * nod + 1, mid + 1, dr, poz, val);
        }
        aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
    }
}
int query(int nod, int st, int dr, int poz, int val)
{
    if(poz <= st && dr <= val)
    {
        return aint[nod];
    }
    else
    {
        int mid = (st + dr) / 2;
        if(val <= mid)
        {
            return query(2 * nod, st, mid, poz, val);
        }
        else
        {
            if(poz > mid)
            {
                return query(2 * nod + 1, mid + 1, dr, poz, val);
            }
        }
        return max(query(2 * nod, st, mid, poz, val), query(2 * nod + 1, mid + 1, dr, poz, val));
    }
}
int querydoi(int poz, int val)
{
    if(arb[poz] == arb[val])
    {
        return query(1, 1, n, min(pozu[poz], pozu[val]), max(pozu[poz], pozu[val]));
    }
    if(nod_height[arb[poz]] < nod_height[arb[val]])
    {
        swap(poz, val);
    }
    return max(query(1, 1, n, pozu[arb[poz]], pozu[poz]), querydoi(tata[arb[poz]], y));
}
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int32_t main(int argc, char * argv[])
{
    fin >> n >> queries;
    for(int i = 1; i <= n; ++i)
    {
        fin >> v[i];
    }
    for(int i = 1; i < n; ++i)
    {
        fin >> x >> y;
        noduri[x].push_back(y);
        noduri[y].push_back(x);
    }
    dfs(1);
    arb[1] = 1;
    dfsdoi(1);
    build(1, 1, n);
    for(int i = 1; i <= queries; ++i)
    {
        fin >> op >> x >> y;
        if(op == 0)
        {
            update(1, 1, n, pozu[x], y);
        }
        else
        {
            fout << querydoi(x, y) << '\n';
        }
    }
    return 0;
}