Cod sursa(job #2817546)

Utilizator mateitudordmDumitru Matei mateitudordm Data 13 decembrie 2021 20:27:42
Problema Heavy Path Decomposition Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.63 kb
#include <bits/stdc++.h>

using namespace std;

///plant- poz in lant, label - lant, asc - lantascendent, qlant - query lant, pos - positia in aint, asc - elementul care este ianintea primului element din lant in arbore, flbl - primul element din lant

int n, greu[100001], w[100001], f[100001], label[100001], plant[100001], asc[100001], pos[100001], flbl[100001], lvl[100001], freelabel = 2, poz;
vector<int> ad[100001];
bool cmp(int a, int b)
{
    return w[a] > w[b];
}
void dfsweight(int nod)
{
    int ok = 0;
    f[nod] = 1;
    for (auto i : ad[nod])
        if (f[i] == 0)
        {
            lvl[i] = lvl[nod] + 1;
            dfsweight(i);
            f[i] = 0;
        }
    for (auto i : ad[nod])
        if (f[i] == 0)
            w[nod] += w[i];
}
void dfslabel(int nod)
{
    f[nod] = 1;
    pos[nod] = ++poz;
    int x = 0;
    while (x < ad[nod].size() && f[ad[nod][x]] == 1)
        x++;
    if (x < ad[nod].size())
    {
        label[ad[nod][x]] = label[nod];
        plant[ad[nod][x]] = plant[nod] + 1;
        for (auto i : ad[nod])
            if (label[i] == 0)
                label[i] = freelabel, plant[i] = 1, asc[freelabel] = nod, flbl[freelabel] = i, freelabel++;
        for (auto i : ad[nod])
            if (f[i] == 0)
                dfslabel(i);
    }
}
struct AINT
{
    int aint[400001];
    void update(int ind, int pos, int val, int st, int dr)
    {
        if (st == dr)
            aint[ind] = val;
        else
        {
            if (pos <= (st + dr) / 2)
                update(2 * ind, pos, val, st, (st + dr) / 2);
            else
                update(2 * ind + 1, pos, val, (st + dr) / 2 + 1, dr);
            aint[ind] = max(aint[2 * ind], aint[2 * ind + 1]);
        }
    }
    int query(int ind, int stq, int drq, int st, int dr)
    {
        if (st >= stq && dr <= drq)
            return aint[ind];
        else
        {
            int maxx = 0;
            if (stq <= (st + dr) / 2)
                maxx = max(maxx, query(2 * ind, stq, drq, st, (st + dr) / 2));
            if (drq > (st + dr) / 2)
                maxx = max(maxx, query(2 * ind + 1, stq, drq, (st + dr) / 2 + 1, dr));
            return maxx;
        }
    }
};
AINT v;
int query(int x, int y)
{
    int maxx = 0, lbl, jos, sus;
    while (x > 0 && y > 0 && label[x] != label[y])
    {
        if (lvl[x] < lvl[y])
            swap(x, y);
        if (asc[label[x]] == 0 || label[asc[label[y]]] == label[x])
            swap(x, y);
        jos = pos[flbl[label[x]]], sus = pos[x];
        maxx = max(maxx, v.query(1, jos, sus, 1, n));
        x = asc[label[x]];
    }
    if (lvl[x] < lvl[y])
        swap(x, y);
    jos = pos[y], sus = pos[x];
    maxx = max(maxx, v.query(1, jos, sus, 1, n));
    return maxx;
}

int main()
{
    ifstream cin("heavypath.in");
    ofstream cout("heavypath.out");
    int m, a, b, i, c;
    for (i = 0; i <= 4 * n; i++)
        v.aint[i] = 0;
    cin >> n >> m;
    for (i = 1; i <= n; i++)
        w[i] = 1, cin >> greu[i];
    for (i = 0; i < n - 1; i++)
    {
        cin >> a >> b;
        ad[a].push_back(b);
        ad[b].push_back(a);
    }
    lvl[1] = 1;
    dfsweight(1);
    for (i = 1; i <= n; i++)
        w[i]--, f[i] = 0, sort(ad[i].begin(), ad[i].end(), cmp);
    label[1] = 1, plant[1] = 1, flbl[1] = 1, flbl[1] = 1;
    dfslabel(1);
    for (i = 1; i <= n; i++)
        v.update(1, pos[i], greu[i], 1, n);
    while (m)
    {
        cin >> c >> a >> b;
        if (c == 0)
            v.update(1, pos[a], b, 1, n);
        else
            cout << query(a, b) << '\n';
        m--;
    }
    return 0;
}