Cod sursa(job #3226664)

Utilizator maiaauUngureanu Maia maiaau Data 22 aprilie 2024 14:33:40
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.19 kb
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int,int>;
#define pb push_back

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

const int N = 1e5+3;

int n, m, k = 1;
int v[N], w[N], niv[N], p[N], pos[N], t[N], a[4*N];
vector<int> e[N];
vector<vector<int>> path;

void read(), dfs(int), build(), updAint(int,int);
int query(int,int), queryAint(int,int,int,int,int);

int main()
{   
    read();
    dfs(1);
    build();

    while (m--){
        int tip, a, b; fin >> tip >> a >> b;
        if (tip) fout << query(a, b) << '\n';
        else updAint(pos[a], b);
    }

    return 0;
}

void read(){
    fin >> n >> m;
    for (int i = 1; i <= n; i++)
        fin >> v[i];
    for (int i = 1; i < n; i++){
        int a, b; fin >> a >> b;
        e[a].pb(b); e[b].pb(a);
    }
}
void dfs(int nod){
    niv[nod] = niv[t[nod]] + 1;
    w[nod] = 1;
    int hvy = 0;
    for (auto it: e[nod]){
        if (it == t[nod]) continue;
        t[it] = nod; dfs(it);
        if (w[it] > w[hvy]) { hvy = it; p[nod] = p[it]; }
        w[nod] += w[it];
    }
    if (!hvy){path.pb({}); p[nod] = path.size() - 1;}
    path[p[nod]].pb(nod);
}
void build(){
    while (k < n) k *= 2; k--;
    int aux = 1;
    for (auto &pth: path){
        reverse(pth.begin(), pth.end());
        for (auto nod: pth){
            a[k + aux] = v[nod];
            pos[nod] = aux++;
        }
    }
    for (int i = k; i; i--)
        a[i] = max(a[2*i], a[2*i+1]);
    
}
int queryAint(int nod, int l, int r, int lq, int rq){
    if (rq < l || r < lq) return 0;
    if (lq <= l && r <= rq) return a[nod];
    
    int mi = (l + r) / 2;
    return max(queryAint(2*nod, l, mi, lq, rq), queryAint(2*nod+1, mi+1, r, lq, rq));

}
void updAint(int nod, int val){
    nod += k; a[nod] = val;
    while ((nod /= 2))
        a[nod] = max(a[2*nod], a[2*nod+1]);
}
int query(int x, int y){
    int ret = 0;
    while (p[x] != p[y]){
        if (niv[path[p[x]][0]] < niv[path[p[y]][0]])
            swap(x, y);
        ret = max(ret, queryAint(1, 1, k+1, pos[path[p[x]][0]], pos[x]));
        x = t[path[p[x]][0]];
    }
    if (niv[x] > niv[y]) swap(x, y);
    ret = max(ret, queryAint(1, 1, k + 1, pos[x], pos[y]));
    return ret;

}