Pagini recente » Profil ciureasilvia | Rating Melvin Abibula (MerlinTheWizard) | Cod sursa (job #3364059) | Cod sursa (job #3363429) | Cod sursa (job #3364039)
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
const int nmax = 100'000, inf = 1'000'000'000;
struct aint {
aint(int n = 0) : n(n) {}
int n, a[2 * nmax];
void update(int p, int v) {
assert(p < n);
a[p += n] = v;
for(p >>= 1; p; p >>= 1) {
a[p] = max(a[p << 1], a[p << 1 | 1]);
}
}
int query(int l, int r) {
int ans = -inf;
for(l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
if(l & 1) ans = max(ans, a[l ++]);
if(r & 1) ans = max(a[-- r], ans);
}
return ans;
}
} t(nmax);
int n, q;
int a[nmax];
vector<int> adj[nmax];
int sz[nmax], depth[nmax], pa[nmax];
int in[nmax], timer = 0;
int heavy_root[nmax];
void initdfs(int u = 0, int p = 0) {
sz[u] = 1, pa[u] = p;
for(auto &v : adj[u]) {
if(v == p) continue;
depth[v] = 1 + depth[u];
initdfs(v, u);
sz[u] += sz[v];
}
}
void dfs(int u = 0, int p = 0) {
in[u] = timer ++;
t.update(in[u], a[u]);
if(adj[u].size() + (u ? -1 : 0) < 1)
return;
nth_element(adj[u].begin(), adj[u].begin(), adj[u].end(), [&](int x, int y){
if(x == p) return false;
if(y == p) return true;
return sz[x] > sz[y];
});
{
int v = adj[u][0];
heavy_root[v] = heavy_root[u];
dfs(v, u);
}
for(int i = 1; i < adj[u].size(); i ++) {
int v = adj[u][i];
if(v == p)
continue;
heavy_root[v] = v;
dfs(v, u);
}
}
int query(int u, int v) {
int ans = -inf;
while(heavy_root[u] != heavy_root[v]) {
if(depth[heavy_root[u]] < depth[heavy_root[v]])
swap(u, v);
ans = max(ans, t.query(in[heavy_root[u]], in[u]));
u = pa[heavy_root[u]];
}
if(in[u] > in[v])
swap(u, v);
ans = max(ans, t.query(in[u], in[v]));
return ans;
}
int main() {
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
cin.tie(0)->sync_with_stdio(0);
cin >> n >> q;
for(int i = 0; i < n; i ++) {
cin >> a[i];
}
for(int i = 0; i < n - 1; i ++) {
int u, v; cin >> u >> v; u --; v --;
adj[u].pb(v), adj[v].pb(u);
}
initdfs();
dfs();
for(; q --;) {
int typ, x, y; cin >> typ >> x >> y;
if(typ == 0) {
x --;
t.update(in[x], y);
} else {
x --; y --;
cout << query(x, y) << '\n';
}
}
}