Cod sursa(job #2732324)

Utilizator PatrickCplusplusPatrick Kristian Ondreovici PatrickCplusplus Data 28 martie 2021 21:34:39
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.34 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

const int nmax = 100005;
int n, m, value[nmax], cnt[nmax], z = 1, p[nmax], whatpos[nmax], whatlant[nmax], nv[nmax];
vector <int> G[nmax];
vector <pair <int, int> > G2[nmax];
vector <int> lant[100], aint[100];

void dfs(int nod, int tata, int nivel){
    cnt[nod] = 1;
    nv[nod] = nivel;
    for (auto it : G[nod]){
        if (it == tata){
            continue;
        }
        dfs(it, nod, nivel + 1);
        G2[nod].push_back({cnt[it], it});
        cnt[nod] += cnt[it];
    }
    sort(G2[nod].begin(), G2[nod].end());
}

void dfs2(int nod){
    whatlant[nod] = z;
    lant[z].push_back(nod);
    whatpos[nod] = lant[z].size();
    for (int i = G2[nod].size() - 1; i >= 0; --i){
        int vecin = G2[nod][i].second;
        p[vecin] = nod;
        dfs2(vecin);
        if (i != 0){
            ++z;
        }
    }
}

void Build(int nod, int st, int dr, int l){
    if (st == dr){
        aint[l][nod] = value[lant[l][st - 1]];
        return;
    }
    int mid = (st + dr) / 2;
    Build(nod * 2, st, mid, l);
    Build(nod * 2 + 1, mid + 1, dr, l);
    aint[l][nod] = max(aint[l][nod * 2], aint[l][nod * 2 + 1]);
}

void Update(int nod, int st, int dr, int l, int pos){
    if (st == dr){
        aint[l][nod] = value[lant[l][st - 1]];
        return;
    }
    int mid = (st + dr) / 2;
    if (pos <= mid) Update(nod * 2, st, mid, l, pos);
    else Update(nod * 2 + 1, mid + 1, dr, l, pos);
    aint[l][nod] = max(aint[l][nod * 2], aint[l][nod * 2 + 1]);
}

int Query(int nod, int st, int dr, int l, int x, int y){
    if (st >= x && dr <= y){
        return aint[l][nod];
    }
    if (st > y || dr < x){
        return 0;
    }
    int mid = (st + dr) / 2;
    return max(Query(nod * 2, st, mid, l, x, y), Query(nod * 2 + 1, mid + 1, dr, l, x, y));
}

int QuerySupremFacutDePatrick(int x, int y){
    int ans = 0;
    while (x != y){
        if (whatlant[x] == whatlant[y]){
            if (whatpos[x] > whatpos[y]){
                swap(x, y);
            }
            ans = max(ans, Query(1, 1, lant[whatlant[x]].size(), whatlant[x], whatpos[x], whatpos[y]));
            y = x;
        }
        else{
            int firstX = lant[whatlant[x]][0], firstY = lant[whatlant[y]][0];
            if (nv[firstX] > nv[firstY]){
                swap(x, y);
            }
            ans = max(ans, Query(1, 1, lant[whatlant[y]].size(), whatlant[y], 1, whatpos[y]));
            y = p[lant[whatlant[y]][0]];
        }
    }
    return ans;
}

int main(){
    fin >> n >> m;
    for (int i = 1; i <= n; ++i){
        fin >> value[i];
    }
    for (int i = 1; i < n; ++i){
        int x, y;
        fin >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    dfs(1, 0, 1);
    dfs2(1);
    for (int i = 1; i <= z; ++i){
        aint[i].resize(4 * lant[i].size() + 4);
        Build(1, 1, lant[i].size(), i);
    }
    while (m--){
        int p, x, y;
        fin >> p >> x >> y;
        if (p == 0){
            value[x] = y;
            Update(1, 1, lant[whatlant[x]].size(), whatlant[x], whatpos[x]);
        }
        else{
            fout << QuerySupremFacutDePatrick(x, y) << "\n";
        }
    }
    fin.close();
    fout.close();
    return 0;
}