Cod sursa(job #3298532)

Utilizator Turcanu_DavidTurcanu David Turcanu_David Data 30 mai 2025 22:10:21
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.43 kb
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using pii = pair<int, int>;

const int MAXN = 1e5 + 5;
const int INF = 1e9;

int n, m;

struct AINT
{
    int v[MAXN * 4];

    void update0(int i, int l, int r, int x, int val)
    {
        if(r < x || x < l)
            return;
        if(l == r)
        {
            v[i] = val;
            return;
        }
        int mid = (l + r) / 2;
        update0(i * 2, l, mid, x, val);
        update0(i * 2 + 1, mid + 1, r, x, val);
        v[i] = max(v[i * 2], v[i * 2 + 1]);
    }

    void update(int x, int val)
    {
        update0(1, 1, n, x, val);
    }

    int query0(int i, int l, int r, int ql, int qr)
    {
        if(r < ql || qr < l)
            return 0;
        if(ql <= l && r <= qr)
            return v[i];
        int mid = (l + r) / 2;
        return max(query0(i * 2, l, mid, ql, qr), query0(i * 2 + 1, mid + 1, r, ql, qr));
    }

    int query(int l, int r)
    {
        return query0(1, 1, n, l, r);
    }
};

struct HLD
{
    int parent[MAXN];
    int head[MAXN];
    int nxt[MAXN];
    int pos[MAXN]; // in aint
    int sz[MAXN];
    int val[MAXN];

    int depth[MAXN];

    bool visited[MAXN];
    vector<int> adj[MAXN];
    vector<int> cd[MAXN];

    AINT aint;
    int cc = 0;

    void dfs(int u)
    {
        if(visited[u])
            return;
        visited[u] = true;
        sz[u] = 1;
        int v1 = 0;
        for(int v : adj[u])
        {
            if(visited[v])
                continue;
            cd[u].push_back(v);
            depth[v] = depth[u] + 1;
            parent[v] = u;
            dfs(v);
            sz[u] += sz[v];
            if(!v1 || sz[v] > sz[v1])
            {
                v1 = v;
            }
        }
        nxt[u] = v1;
    }

    void dfs1(int u)
    {
        pos[u] = ++cc;
        if(cd[u].size() == 0)
            return;
        for(int v : cd[u])
        {
            if(v == nxt[u])
            {
                head[v] = head[u];
                continue;
            }
            head[v] = v;
        }
        dfs1(nxt[u]);
        for(int v : cd[u])
        {
            if(v == nxt[u])
                continue;
            dfs1(v);
        }
    }

    void init()
    {
        parent[1] = 1;
        head[1] = 1;
        dfs(1);
        dfs1(1);
        for(int i = 1; i <= n; i++)
        {
            aint.update(pos[i], val[i]);
        }
    }

    void update(int x, int val)
    {
        aint.update(pos[x], val);
    }

    int query(int u, int v)
    {
        int ans = 0;
        while(head[u] != head[v])
        {
            if(depth[head[u]] < depth[head[v]])
                swap(u, v);
            ans = max(ans, aint.query(pos[head[u]], pos[u]));
            u = parent[head[u]];
        }
        if(depth[u] > depth[v])
            swap(u, v);
        ans = max(ans, aint.query(pos[u], pos[v]));
        return ans;
    }
};

HLD hld;

int32_t main()
{
    ifstream cin("heavypath.in");
    ofstream cout("heavypath.out");
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
    {
        cin >> hld.val[i];
    }
    for(int i = 1; i < n; i++)
    {
        int u, v;
        cin >> u >> v;
        hld.adj[u].push_back(v);
        hld.adj[v].push_back(u);
    }
    hld.init();
    while(m--)
    {
        int t, x, y;
        cin >> t >> x >> y;
        if(t == 0)
        {
            hld.update(x, y);
        }
        else
        {
            cout << hld.query(x, y) << '\n';
        }
    }
    return 0;
}