Cod sursa(job #3193018)

Utilizator Chris_BlackBlaga Cristian Chris_Black Data 13 ianuarie 2024 19:30:23
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.27 kb
#include <bits/stdc++.h>
#define vi vector<int>
#define vvi vector<vi>
#define FOR(i, a, b) for(int i = a; i <= b; ++i)
#define FORR(i, a, b) for(int i = a; i >= b; --i)
#define pb push_back

using namespace std;
const string TASK("heavypath");
ifstream fin(TASK + ".in");
ofstream fout(TASK + ".out");
#define cin fin
#define cout fout
const int N = 1e5 + 9;

int n, m, v[N];
vvi G(N);
int tree[2 * N], t[N], dep[N], w[N], heavy_son[N], head[N], pos[N];
int sp[N];

void Update(int p, int val)
{
    for(tree[p += n] = val; p > 1; p >>= 1)tree[p >> 1] = max(tree[p], tree[p ^ 1]);
}
int Query(int l, int r)
{
    int res = INT_MIN;
    for(l += n, r += n; l <= r; l >>= 1, r >>= 1)
    {
        if(l & 1)res = max(res, tree[l ++]);
        if(!(r & 1))res = max(res, tree[r --]);
    }

    return res;
}
int Answer(int a, int b)
{
    int res = INT_MIN;
    for(; head[a] != head[b]; a = t[head[a]])
    {
        if(dep[head[a]] < dep[head[b]])swap(a, b);
        res = max(res, sp[a]);
    }

    if(dep[a] > dep[b])swap(a, b);
    res = max(res, Query(pos[a], pos[b]));

    return res;
}

void Dfs(int x)
{
    w[x] = 1;
    heavy_son[x] = -1;

    for(auto y : G[x])
    {
        if(y == t[x])continue;

        t[y] = x;
        dep[y] = dep[x] + 1;

        Dfs(y);

        w[x] += w[y];
        if(heavy_son[x] == -1 || w[heavy_son[x]] < w[y])
            heavy_son[x] = y;
    }
}

int position;
void Decompose(int x, int hd)
{
    head[x] = hd;
    pos[x] = position++;
    Update(pos[x], v[x]);

    if(heavy_son[x] != -1)
    {
        sp[heavy_son[x]] = max(sp[x], v[heavy_son[x]]);
        Decompose(heavy_son[x], hd);
    }

    for(auto y : G[x])
        if(y != heavy_son[x] && y != t[x])
            Decompose(y, y);
}

int main()
{
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);

    cin >> n >> m;
    FOR(i, 1, n)cin >> v[i];

    FOR(i, 1, n)sp[i] = v[i];

    int a, b;
    FOR(i, 2, n)
    {
        cin >> a >> b;
        G[a].pb(b);
        G[b].pb(a);
    }

    Dfs(1);
    Decompose(1, 1);

    int op, x, y;
    FOR(i, 1, m)
    {
        cin >> op >> x >> y;
        if(op == 0)Update(pos[x], y);
        else cout << Answer(x, y) << '\n';
    }
    return 0;
}