Cod sursa(job #3144569)

Utilizator NanuGrancea Alexandru Nanu Data 8 august 2023 21:20:10
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.83 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f ("heavypath.in");
ofstream g ("heavypath.out");

constexpr int NMAX = 1e5 + 5;

int N, M;

int V[NMAX];
vector <int> G[NMAX];
int arb[4*NMAX];

void Update_Tree (int nod, int a, int b, int poz, int val) {
    if (a == b) {
        arb[nod] = val;
        return;
    }

    int mij = (a + b) / 2;

    if (poz <= mij) Update_Tree(2*nod, a, mij, poz, val);
    else Update_Tree(2*nod+1, mij+1, b, poz, val);

    arb[nod] = max(arb[2*nod], arb[2*nod+1]);
}

int Query_Tree (int nod, int a, int b, int qa, int qb) {
    if (qa <= a && b <= qb) return arb[nod];

    int mij = (a + b) / 2;
    int ans_L = 0, ans_R = 0;

    if (qa <= mij) ans_L = Query_Tree(2*nod, a, mij, qa, qb);
    if (mij < qb) ans_R = Query_Tree(2*nod+1, mij+1, b, qa, qb);

    return max(ans_L, ans_R);
}

void Read () {
    f >> N >> M;

    for (int i = 1; i <= N; ++ i )
        f >> V[i];

    for (int i = 1; i < N; ++ i ) {
        int x, y;
        f >> x >> y;

        G[x].push_back(y);
        G[y].push_back(x);
    }
}

int Max_Son[NMAX];
int Size[NMAX];
int chains;
int ID[NMAX];
int Size_ID[NMAX];
int First[NMAX];
int Level[NMAX];
int Dad[NMAX];
int poz[NMAX];
int cnt = 0;

void Dfs (int node, int dad = -1) {
    Max_Son[node] = -1;
    Size[node] = 1;
    Dad[node] = dad;

    for (auto it : G[node]) {
        if (it == dad) continue;

        Level[it] = Level[node] + 1;
        Dfs(it, node);

        if (Max_Son[node] == -1 || Size[Max_Son[node]] < Size[it])
            Max_Son[node] = it;

        Size[node] += Size[it];
    }
}

void Split (int node) {
    ID[node] = chains;
    poz[node] = ++cnt;
    Size_ID[chains] ++;

    if (Max_Son[node] == -1) return;

    Split(Max_Son[node]);

    for (auto it : G[node]) {
        if (it == Dad[node] || it == Max_Son[node]) continue;

        ++ chains;
        First[chains] = it;
        Split(it);
    }
}

void HeavyPath () {
    Dfs(1);

    Split(1);

    for (int i = 1; i <= N; ++ i )
        Update_Tree(1, 1, N, poz[i], V[i]);
}

void Update (int x, int val) {
    Update_Tree(1, 1, N, poz[x], val);
}

int Query (int x, int y) {
    if (ID[x] == ID[y])
        return Query_Tree(1, 1, N, min(poz[x], poz[y]), max(poz[x], poz[y]));

    if (Level[First[ID[x]]] < Level[First[ID[y]]])
        swap(x, y);

    int ans = Query_Tree(1, 1, N, poz[First[ID[x]]], poz[x]);

    return max(ans, Query(Dad[First[ID[x]]], y));
}

void Solve () {
    for (int i = 1; i <= M; ++ i ) {
        int tip, x, y;
        f >> tip >> x >> y;

        if (tip == 0) {
            Update(x, y);
        }
        else {
            g << Query(x, y) << '\n';
        }
    }
}

int main () {
    Read();

    HeavyPath();

    Solve();

    return 0;
}