Pagini recente » Cod sursa (job #85745) | Cod sursa (job #117951) | Cod sursa (job #2196084) | Cod sursa (job #969596) | Cod sursa (job #2920130)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
const int INF = 1e9;
int n, m, labels = 1;
vector<int> nodeValue, subtreeSize, parent, level, nodeLabel, heavyTour, pos, segTree;
vector<vector<int>> adj;
void dfs(int u = 1, int v = -1, int lev = 1) {
subtreeSize[u] = 1;
parent[u] = v;
level[u] = lev;
for(const auto &it: adj[u]) if(it != v) {
dfs(it, u, lev + 1);
subtreeSize[u] += subtreeSize[it];
}
}
vector<int> head = {1};
void decomp(int u = 1, int v = -1) {
nodeLabel[u] = head.size() - 1;
heavyTour.push_back(u);
pos[u] = heavyTour.size() - 1;
int heavyNode = 0;
for(const auto &it: adj[u]) if(it != v) {
if(subtreeSize[it] > subtreeSize[heavyNode]) {
heavyNode = it;
}
}
if(heavyNode) {
decomp(heavyNode, u);
for(const auto &it: adj[u]) if(it != v && it != heavyNode) {
head.push_back(it);
decomp(it, u);
}
}
}
void build() {
segTree = vector<int> (2 * heavyTour.size() + 1);
for(int i = (int) heavyTour.size(); i < (int) (heavyTour.size() << 1); i++) {
segTree[i] = nodeValue[heavyTour[i - heavyTour.size()]];
}
for(int i = (int) heavyTour.size() - 1; i >= 1; i--) {
segTree[i] = max(segTree[(i << 1)], segTree[(i << 1) + 1]);
}
}
void update(int pos, int newVal) {
pos += heavyTour.size();
segTree[pos] = newVal;
for(int i = (pos >> 1); i >= 1; i >>= 1) {
segTree[i] = max(segTree[(i << 1)], segTree[(i << 1) + 1]);
}
}
int query(int a, int b) {
if(a > b) {
swap(a, b);
}
int ret = -INF;
for(a += heavyTour.size(), b += heavyTour.size(); a <= b; a >>= 1, b >>= 1) {
if(a & 1) {
ret = max(ret, segTree[a++]);
}
if((b ^ 1) & 1) {
ret = max(ret, segTree[b--]);
}
}
return ret;
}
int chainQuery(int u, int v) {
int ret = -INF;
while(nodeLabel[u] != nodeLabel[v]) {
cout << u << " " << v << '\n';
if(level[head[nodeLabel[u]]] > level[head[nodeLabel[v]]]) {
ret = max(ret, query(pos[u], pos[head[nodeLabel[u]]]));
u = parent[head[nodeLabel[u]]];
} else {
ret = max(ret, query(pos[v], pos[head[nodeLabel[v]]]));
v = parent[head[nodeLabel[v]]];
}
}
cout << u << " " << v << "\n\n";
ret = max(ret, query(pos[u], pos[v]));
return ret;
}
int main() {
fin >> n >> m;
adj = vector<vector<int>> (n + 1);
nodeValue = subtreeSize = parent = level = nodeLabel = pos = vector<int> (n + 1);
for(int i = 1; i <= n; i++) {
fin >> nodeValue[i];
}
for(int i = 1; i < n; i++) {
int u, v;
fin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
dfs();
subtreeSize[0] = -INF;
decomp();
// for(const auto &it: heavyTour) {
// cout << it << " " << nodeLabel[it] << " " << head[nodeLabel[it]] << '\n';
// }
// cout << '\n';
build();
for(int i = 1; i <= m; i++) {
int task, x, y;
fin >> task >> x >> y;
if(task == 0) {
nodeValue[x] = y;
update(pos[x], nodeValue[x]);
} else {
fout << chainQuery(x, y) << '\n';
}
}
return 0;
}