Pagini recente » Cod sursa (job #3003111) | Cod sursa (job #2404445) | Cod sursa (job #2474775) | Cod sursa (job #2395893) | Cod sursa (job #2986025)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
const int NMAX = 1e5;
int n, m;
int v[NMAX + 1];
vector<int> adj[NMAX + 1];
int sz[NMAX + 1], heavyChild[NMAX + 1], lvl[NMAX + 1], par[NMAX + 1];
void dfs(int u = 1, int v = 0) {
sz[u] = 1;
for(const auto &it: adj[u]) if(it != v) {
par[it] = u;
lvl[it] = lvl[u] + 1;
dfs(it, u);
sz[u] += sz[it];
if(sz[it] > sz[heavyChild[u]]) {
heavyChild[u] = it;
}
}
}
int lbl[NMAX + 1]; // lbl[i] =def= numarul de ordine al lantului din care face parte nodul i, lbl[u] == lbl[v] <=> u si v sunt in acelasi lant (dupa descompunere), a nu se confunda cu lvl!!!
vector<int> head = {1}; // head[i] =def= capul lantului (lantul cu numarul de ordine i) format din nodurile u, etichetate cu lbl[u] = i, initial radacina este capul primului lant.
vector<int> heavyFirst;
int tin[NMAX + 1]; // tin[i] =def= pozitia (timpul de intrare) nodului i in parcurgerea heavyFirst.
void decomp(int u = 1, int v = 0) {
heavyFirst.emplace_back(u);
tin[u] = heavyFirst.size() - 1;
lbl[u] = head.size() - 1;
if(heavyChild[u] != 0) {
decomp(heavyChild[u], u);
}
for(const auto &it: adj[u]) if(it != v && it != heavyChild[u]) {
head.emplace_back(it); // lant nou -> cap nou -> eticheta noua.
decomp(it, u);
}
}
void maxSelf(int &x, int y) {
if(y > x) {
x = y;
}
}
int segTree[2 * NMAX + 1];
void build() {
for(int i = 0; i < n; i++) {
segTree[n + i] = v[heavyFirst[i]];
}
for(int i = n - 1; i >= 1; i--) {
segTree[i] = max(segTree[i << 1], segTree[i << 1 | 1]);
}
}
void update(int pos, int val) {
pos += n;
segTree[pos] = val;
pos >>= 1;
while(pos >= 1) {
segTree[pos] = max(segTree[pos << 1], segTree[pos << 1 | 1]);
pos >>= 1;
}
}
int query(int a, int b) {
if(a > b) {
swap(a, b);
}
int ret = 0;
a += n;
b += n;
while(a <= b) {
if(a & 1) {
maxSelf(ret, segTree[a]);
a++;
}
if(!(b & 1)) {
maxSelf(ret, segTree[b]);
b--;
}
a >>= 1;
b >>= 1;
}
return ret;
}
int chainQuery(int u, int v) {
int ret = 0;
while(lbl[u] != lbl[v]) {
if(lvl[head[lbl[u]]] > lvl[head[lbl[v]]]) {
maxSelf(ret, query(tin[u], tin[head[lbl[u]]]));
u = par[head[lbl[u]]];
} else {
maxSelf(ret, query(tin[v], tin[head[lbl[v]]]));
v = par[head[lbl[v]]];
}
}
maxSelf(ret, query(tin[u], tin[v]));
return ret;
}
int main() {
ios_base :: sync_with_stdio(false);
fin >> n >> m;
for(int i = 1; i <= n; i++) {
fin >> v[i];
}
for(int i = 1; i < n; i++) {
int u, v;
fin >> u >> v;
adj[u].emplace_back(v);
adj[v].emplace_back(u);
}
dfs();
decomp();
build();
for(int i = 1; i <= m; i++) {
int t, x, y;
fin >> t >> x >> y;
if(t == 0) {
update(tin[x], y);
} else {
fout << chainQuery(x, y) << '\n';
}
}
fin.close();
fout.close();
return 0;
}