Cod sursa(job #3205137)

Utilizator AswVwsACamburu Luca AswVwsA Data 18 februarie 2024 21:45:09
Problema Heavy Path Decomposition Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.73 kb
#include <fstream>
#include <vector>
#define ll long long
using namespace std;

const int NMAX = 1e5;

vector <int> g[NMAX + 1];
int s[NMAX + 1];
int head[NMAX + 1];
int pos[NMAX + 1];
int comp[NMAX + 1];
int sus[NMAX + 1];
int d[NMAX + 1];

void dfs_sub(int nod, int parent)
{
    d[nod] = d[parent] + 1;
    sus[nod] = parent;
    s[nod] = 1;
    for (int x : g[nod])
        if (x != parent)
        {
            dfs_sub(x, nod);
            s[nod] += s[x];
        }
}

int nr;

void dfs_heavy(int nod, int parent, int label)
{
    static int time = 0;
    pos[nod] = ++time;
    comp[nod] = label;
    for (int x : g[nod])
        if (x != parent)
        {
            if (s[x] <= s[nod] / 2)
            {
                nr++;
                head[nr] = x;
                dfs_heavy(x, nod, nr);
            }
            else
                dfs_heavy(x, nod, label);
        }
}

int v[NMAX + 1];

int aint[4 * NMAX + 1];

void update(int node, int st, int dr, int poz, int val)
{
    if (dr < poz or st > poz)
        return ;
    if (st == dr)
    {
        aint[node] = val;
        return ;
    }
    int med = ((st + dr) >> 1);
    update(node << 1, st, med, poz, val);
    update(node << 1 | 1, med + 1, dr, poz, val);
    aint[node] = max(aint[node << 1], aint[node << 1 | 1]);
}

int query(int node, int st, int dr, int a, int b)
{
    if (dr < a or st > b)
        return 0;
    if (a <= st and dr <= b)
        return aint[node];
    int med = ((st + dr) >> 1);
    int v1 = query(node << 1, st, med, a, b);
    int v2 = query(node << 1 | 1, med + 1, dr, a, b);
    return max(v1, v2);
}

int n;

int solve(int a, int b)
{
    int ans = 0;
    while (comp[a] != comp[b])
    {
        if (d[head[comp[a]]] < d[head[comp[b]]])
            swap(a, b);
        ans = max(ans, query(1, 1, n, pos[head[comp[a]]], pos[a]));
        a = sus[head[comp[a]]];
    }
    if (pos[a] > pos[b])
        swap(a, b);
    ans = max(ans, query(1, 1, n, pos[a], pos[b]));
    return ans;
}

signed main()
{
    ifstream cin("heavypath.in");
    ofstream cout("heavypath.out");
    int i, q;
    cin >> n >> q;
    for (i = 1; i <= n; i++)
        cin >> v[i];
    for (i = 2; i <= n; i++)
    {
        int a, b;
        cin >> a >> b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    dfs_sub(1, 0);
    nr = 1;
    head[1] = 1;
    dfs_heavy(1, 0, 1);
    for (i = 1; i <= n; i++)
        update(1, 1, n, pos[i], v[i]);
    while (q--)
    {
        int op, a, b;
        cin >> op >> a >> b;
        if (op == 0)
        {
            update(1, 1, n, pos[a], b);
        }
        else
            cout << solve(a, b) << "\n";
    }
    return 0;
}