Cod sursa(job #2932503)

Utilizator geniucosOncescu Costin geniucos Data 3 noiembrie 2022 00:40:13
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.69 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <stack>
#include <cassert>
#include <map>
#include <numeric>
#include <cstring>
#include <set>
#include <ctime>
#include <queue>
#include <cmath>
#include <iomanip>
#include <iterator>
#include <bitset>
#include <unordered_map>
#include <complex>
#include <unordered_set>
#include <chrono>
#include <random>
#include <array>
#include <functional>
#include <random>

///6:21
using namespace std;

const int maxN = 100009;
int N, M, nr, aint[4 * maxN], q[maxN], pos[maxN], sz[maxN], t[maxN], fst[maxN], a[maxN], lev[maxN];
vector<int> v[maxN], sons[maxN];

void dfsSz(int nod) {
    int biggestSon = -1;
    sz[nod] = 1;
    for (auto it : v[nod])
        if (it != t[nod]) {
            t[it] = nod, lev[it] = lev[nod] + 1, dfsSz (it);
            if (biggestSon == -1 || sz[it] > sz[biggestSon])
                biggestSon = it;
            sz[nod] += sz[it];
        }
    if (biggestSon != -1)
        sons[nod].push_back(biggestSon);
    for (auto it : v[nod])
        if (it != t[nod] && it != biggestSon)
            sons[nod].push_back(it);
}

void dfs(int nod) {
    pos[nod] = ++nr, q[nr] = nod;
    for (auto it : sons[nod]) {
        fst[it] = (it == sons[nod][0]) ? fst[nod] : it;
        dfs(it);
    }
}

void build(int nod, int st, int dr) {
    if (st == dr) {
        aint[nod] = a[q[st]];
        return ;
    }
    int mid = (st + dr) >> 1, f1 = nod << 1, f2 = f1 | 1;
    build(f1, st, mid);
    build(f2, mid + 1, dr);
    aint[nod] = max(aint[f1], aint[f2]);
}

void update(int nod, int st, int dr, int pos) {
    if (st == dr) {
        aint[nod] = a[q[st]];
        return ;
    }
    int mid = (st + dr) >> 1, f1 = nod << 1, f2 = f1 | 1;
    if (pos <= mid) update(f1, st, mid, pos);
    else update(f2, mid + 1, dr, pos);
    aint[nod] = max(aint[f1], aint[f2]);
}

int ansQ = 0;
void query(int nod, int st, int dr, int x, int y) {
    /*if (nod == 1)
        printf("queried [%d, %d]", x, y);*/
    if (x <= st && dr <= y) {
        if (x == st) ansQ = aint[nod];
        else ansQ = max(ansQ, aint[nod]);
        return ;
    }
    int mid = (st + dr) >> 1, f1 = nod << 1, f2 = f1 | 1;
    if (x <= mid) query(f1, st, mid, x, y);
    if (mid < y) query(f2, mid + 1, dr, x, y);
    //if (nod == 1) printf("->%d ", ansQ);
}

int query(int x, int y) {
    //printf("recursed to [%d, %d]", x, y);
    if (fst[x] == fst[y]) {
        x = pos[x], y = pos[y];
        if (x > y) swap(x, y);
        query(1, 1, N, x, y);
        return ansQ;
    }
    if (lev[fst[x]] > lev[fst[y]])
        swap(x, y);
    query(1, 1, N, pos[fst[y]], pos[y]);
    int ans = ansQ;
    ans = max(ans, query(x, t[fst[y]]));
    return ans;
}

int main() {
    //freopen("../input", "r", stdin);
    //freopen("../output", "w", stdout);

    freopen("heavypath.in", "r", stdin);
    freopen("heavypath.out", "w", stdout);

    scanf("%d %d", &N, &M);
    for (int i=1; i<=N; i++)
        scanf("%d", &a[i]);
    for (int i=1; i<N; i++) {
        int x, y;
        scanf("%d %d", &x, &y);
        v[x].push_back(y);
        v[y].push_back(x);
    }
    t[1] = -1, dfsSz(1);
    fst[1] = 1, dfs(1), assert(nr == N);
    build(1, 1, N);
    /*for (int i=1; i<=N; i++) {
        if (fst[q[i]] == q[i])
            printf("|");
        printf("%d ", q[i]);
    }
    printf("\n");*/
    while (M --) {
        int type, x, y;
        scanf("%d %d %d", &type, &x, &y);
        if (type == 0) {
            a[x] = y;
            update(1, 1, N, pos[x]);
            continue;
        }
        printf("%d\n", query(x, y));
    }
    return 0;
}

/*const int seed = time (0);
mt19937 gen (seed);
long long getRand(long long a, long long b) {return uniform_int_distribution < long long > (a, b) (gen);}*/