Cod sursa(job #1412454)

Utilizator 4ONI2015oni2015 4ONI2015 Data 1 aprilie 2015 12:08:07
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.07 kb
#include <bits/stdc++.h>
#define N 100005
#define pb push_back

using namespace std;
int n, m, tata[N], niv[N], poz[N], lant[N], A[N], i, a, b, sol, x, y, gr[N], nrl, nn, t;
vector<int>v[N], arb[N], p[N];

void build(int nod, int l, int r)
{
    if(l == r)
    {
        arb[i][nod] = A[p[i][l]];
        return;
    }
    int mij = (l + r) / 2, fs = 2 * nod;
    build(fs, l, mij);
    build(fs + 1, mij + 1, r);
    arb[i][nod] = max(arb[i][fs], arb[i][fs + 1]);
}
void query(int nod, int l, int r)
{
    if(b < l || a > r)
        return;
    if(a <= l && b >= r)
    {
        sol = max(sol, arb[lant[x]][nod]);
        return;
    }
    int mij = (l + r) / 2, fs = 2 * nod;
    query(fs, l, mij);
    query(fs + 1, mij + 1, r);
}
void update(int nod, int l, int r)
{
    if(l == r)
    {
        arb[lant[x]][nod] = y;
        return;
    }
    int mij = (l + r) / 2, fs = 2 * nod;
    if(mij < poz[x])
        update(fs + 1, mij + 1, r);
    else
        update(fs, l, mij);
    arb[lant[x]][nod] = max(arb[lant[x]][fs], arb[lant[x]][fs + 1]);
}
void df(int nod, int Tata)
{
    gr[nod] = 1;
    int fg = 0;
    for(auto it : v[nod])
    {
        if(it == Tata)
            continue;
        tata[it] = nod;
        niv[it] = niv[nod] + 1;
        df(it, nod);
        gr[nod] += gr[it];
        if(gr[fg] < gr[it])
            fg = it;
    }
    if(v[nod].size() == 1 && nod != 1)
    {
        nrl++;
        p[nrl].pb(0);
        p[nrl].pb(nod);
        poz[nod] = 1;
        lant[nod] = nrl;
        return;
    }
    p[lant[fg]].pb(nod);
    poz[nod] = p[lant[fg]].size() - 1;
    lant[nod] = lant[fg];
}
int main()
{
    freopen("heavypath.in", "r", stdin);
    freopen("heavypath.out", "w", stdout);
    scanf("%d%d", &n, &m);
    for(i = 1; i <= n; i++)
        scanf("%d", &A[i]);
    for(i = 1; i < n; i++)
    {
        scanf("%d%d", &x, &y);
        v[x].pb(y);
        v[y].pb(x);
    }
    niv[1] = 1;
    df(1, 0);
    for(i = 1; i <= nrl; i++)
    {
        reverse(p[i].begin() + 1, p[i].end());
        nn = p[i].size();
        arb[i].resize(4 * nn + 5);
        build(1, 1, nn - 1);
    }
    for(i = 1; i <= n; i++)
        poz[i] = p[lant[i]].size() - poz[i];
    for(; m; m--)
    {
        scanf("%d%d%d", &t, &x, &y);
        if(!t)
            update(1, 1, p[lant[x]].size() - 1);
        else
        {
            sol = 0;
            for(;;)
            {
                if(lant[x] == lant[y])
                {
                    a = min(poz[x], poz[y]);
                    b = max(poz[x], poz[y]);
                    nn = p[lant[x]].size();
                    query(1, 1, nn - 1);
                    printf("%d\n", sol);
                    break;
                }
                if(niv[p[lant[x]][1]] < niv[p[lant[y]][1]])
                    swap(x, y);
                a = 1;
                b = poz[x];
                nn = p[lant[x]].size();
                query(1, 1, nn - 1);
                x = tata[p[lant[x]][1]];
            }
        }
    }
    return 0;
}