Pagini recente » Cod sursa (job #745332) | Cod sursa (job #1728538) | Cod sursa (job #1293254) | Cod sursa (job #2077639) | Cod sursa (job #2047106)
#include <utility>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
static const int kMagic = 256;
class SqrtTree {
private:
void dfs(int node) {
for (auto&& son : G[node])
if (parent[node] != son) {
parent[son] = node;
depth[son] = depth[node] + 1;
dfs(son);
}
}
void dfs_push(int node, int group) {
for (auto&& son : G[node])
if (parent[node] != son && super_parent[son] == group) {
super_value[son] = max(V[son], super_value[node]);
dfs_push(son, group);
}
}
void dfs_value(int node) {
for (auto&& son : G[node])
if (parent[node] != son) {
if (super_parent[son] == super_parent[node])
super_value[son] = max(super_value[node], super_value[son]);
dfs_value(son);
}
}
void initialize() {
parent.resize(N);
depth.resize(N);
fill(parent.begin(), parent.end(), -1);
dfs(0);
super_parent.resize(N);
fill(super_parent.begin(), super_parent.end(), -1);
super_parent[0] = 0;
for (int i = 1; i < N; ++i) {
if (super_parent[i] != -1)
continue;
int iter = parent[i];
while (depth[iter] % kMagic && super_parent[iter] == -1)
iter = parent[iter];
if (depth[iter] % kMagic)
super_parent[i] = super_parent[iter];
else
super_parent[i] = super_parent[iter] = iter;
for (int j = parent[i]; j != iter; j = parent[j])
super_parent[j] = super_parent[i];
}
super_value = V;
dfs_value(0);
}
public:
SqrtTree() = default;
SqrtTree(vector<int>& _V, vector< vector<int> >& _G) : V(move(_V)), G(move(_G)), N((int)V.size()) {
initialize();
}
int query(int x, int y) const {
int ans = 0;
while (super_parent[x] != super_parent[y]) {
if (depth[x] >= depth[y]) {
if (ans < super_value[x])
ans = super_value[x];
x = parent[super_parent[x]];
} else {
if (ans < super_value[y])
ans = super_value[y];
y = parent[super_parent[y]];
}
}
while (x != y) {
if (depth[x] >= depth[y]) {
if (ans < V[x])
ans = V[x];
x = parent[x];
} else {
if (ans < V[y])
ans = V[y];
y = parent[y];
}
}
return max(ans, V[x]);
}
void set_value(int node, const int& new_value) {
V[node] = new_value;
super_value[node] = new_value;
if (parent[node] != -1 && super_parent[parent[node]] == super_parent[node])
super_value[node] = max(super_value[node], super_value[parent[node]]);
dfs_push(node, super_parent[node]);
}
vector<int> V;
vector< vector<int> > G;
vector<int> parent, super_parent, super_value;
vector<int> depth;
int N;
};
int main() {
#ifdef LOCAL
ifstream cin("a.in");
#else
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
#endif
int N, Q; cin >> N >> Q;
vector<int> V(N);
for (int i = 0; i < N; ++i)
cin >> V[i];
vector<vector<int> > G(N);
for (int i = 1; i < N; ++i) {
int x, y; cin >> x >> y; x--; y--;
G[x].push_back(y);
G[y].push_back(x);
}
SqrtTree tree(V, G);
while (Q--) {
int type; cin >> type;
if (type == 0) {
int node, value; cin >> node >> value; node--;
tree.set_value(node, value);
} else {
int x, y; cin >> x >> y; x--; y--;
cout << tree.query(x, y) << '\n';
}
}
}