Cod sursa(job #2417621)

Utilizator akaprosAna Kapros akapros Data 30 aprilie 2019 16:46:05
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.45 kb
#include <bits/stdc++.h>
#define maxN 100002
#define inf 0x3fffffff
using namespace std;

FILE *fin = freopen("heavypath.in", "r", stdin);
FILE *fout = freopen("heavypath.out", "w", stdout);

int n, m;
int v[maxN];

int nrCh, sub[maxN], lev[maxN], pos[maxN], head[maxN];
vector < int > V[maxN], Chain[maxN];
int ChainId[maxN];

int ans;

class st
{
public :
    vector < int > aint;
    inline void update(int node, int l, int r, int p, int val)
    {
        if (l > r)
            return;
        if (l == r)
        {
            aint[node] = val;
            return ;
        }
        int lson = 2 * node, rson = lson + 1, mid = (l + r) >> 1;
        if (p <= mid)
            update(lson, l, mid, p, val);
        else
            update(rson, mid + 1, r, p, val);
        aint[node] = max(aint[lson], aint[rson]);
    }
    inline int query(int node, int l, int r, int x, int y)
    {
        if (l > r)
            return -inf;
        if (l == x && r == y)
            return aint[node];
        int lson = 2 * node, rson = lson + 1, mid = (l + r) >> 1;
        if (y <= mid)
            return query(lson, l, mid, x, y);
        else
        {
            if (x > mid)
                return query(rson, mid + 1, r, x, y);
            else
                return max(query(lson, l, mid, x, mid), query(rson, mid + 1, r, mid + 1, y));
        }
    }
} trees[maxN];

void dfs(int x)
{
    int spSon = -1;
    sub[x] = 1;
    for (int y : V[x])
        if (!sub[y])
        {
            dfs(y);
            lev[y] = lev[x] + 1;
            sub[x] += sub[y];
            if (spSon == -1 || sub[spSon] < sub[y])
                spSon = y;
            head[ChainId[y]] = x;
        }
    if (spSon == -1)
    {
        ++ nrCh;
        pos[x] = 1;
        ChainId[x] = nrCh;
        Chain[nrCh].push_back(x);
    }
    else
    {
        ChainId[x] = ChainId[spSon];
        head[ChainId[x]] = 0;
        pos[x] = pos[spSon] + 1;
        Chain[ChainId[x]].push_back(x);
    }
}
void compAint()
{
    for (int i = 1; i <= nrCh; ++ i)
    {
        trees[i].aint.resize(Chain[i].size() * 4);
        for (int j = 0; j < Chain[i].size(); ++ j)
            trees[i].update(1, 1, Chain[i].size(), j + 1, v[Chain[i][j]]);
    }
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++ i)
        scanf("%d", &v[i]);

    for (int i = 0; i < n - 1; ++ i)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        V[x].push_back(y);
        V[y].push_back(x);
    }
    dfs(1);
    compAint();
    for (int x = 1; x <= n; ++ x)
        trees[ChainId[x]].update(1, 1, Chain[ChainId[x]].size(), pos[x], v[x]);
    while (m --)
    {
        int ty, x, y;
        scanf("%d%d%d", &ty, &x, &y);
        if (!ty)
            trees[ChainId[x]].update(1, 1, Chain[ChainId[x]].size(), pos[x], y);
        else
        {
            ans = -inf;
            while (ChainId[x] != ChainId[y])
            {
                if (lev[head[ChainId[x]]] < lev[head[ChainId[y]]])
                    swap(x, y);
                ans = max(ans, trees[ChainId[x]].query(1, 1, Chain[ChainId[x]].size(), pos[x], Chain[ChainId[x]].size()));
                x = head[ChainId[x]];
            }
            if (pos[x] > pos[y]) swap(x, y);
            ans = max(ans, trees[ChainId[x]].query(1, 1, Chain[ChainId[x]].size(), pos[x], pos[y]));
            printf("%d\n", ans);
        }
    }

    return 0;
}