Pagini recente » Cod sursa (job #2064039) | Cod sursa (job #2096175) | Cod sursa (job #2591830) | Cod sursa (job #1401313) | Cod sursa (job #3263151)
/*
! Abordarea Heavy Path
*/
#include <bits/stdc++.h>
using namespace std;
#define INFILE "heavypath.in"
#define OUTFILE "heavypath.out"
struct AINT {
private:
int n;
vector<int> aint;
public:
AINT(){}
AINT(int _n) : n(_n) {
aint.resize(2 * n + 1, 0);
}
void update(int position, int value){
for(aint[position += n - 1] = value; position > 1; position >>= 1){
aint[position >> 1] = max(aint[position], aint[position ^ 1]);
}
}
int query(int queryLeft, int queryRight){
int ans = 0;
for(queryLeft += n - 1, queryRight += n; queryLeft < queryRight; queryLeft >>= 1, queryRight >>= 1){
if(queryLeft & 1) ans = max(ans, aint[queryLeft++]);
if(queryRight & 1) ans = max(ans, aint[--queryRight]);
}
return ans;
}
};
const int N_MAX = 1e5;
const int M_MAX = 1e5;
int nodes, queries;
int a[N_MAX + 5];
int sz[N_MAX + 5];
int level[N_MAX + 5];
int parent[N_MAX + 5];
int heavySon[N_MAX + 5];
int paths;
int timer;
int tin[N_MAX + 5];
int head[N_MAX + 5];
int label[N_MAX + 5];
vector<int> adj[N_MAX + 5];
AINT aint;
void dfs(int node){
level[node] = level[parent[node]] + 1;
sz[node] = 1;
heavySon[node] = 0;
for(auto &to : adj[node]){
if(to != parent[node]){
parent[to] = node;
dfs(to);
sz[node] += sz[to];
if(sz[to] > sz[heavySon[node]]){
heavySon[node] = to;
}
}
}
}
void decomposition(int node){
tin[node] = ++timer;
if(heavySon[node] != 0){
decomposition(heavySon[node]);
label[node] = label[heavySon[node]];
}
else {
label[node] = ++paths;
}
head[label[node]] = node;
for(auto &to : adj[node]){
if(to != parent[node] && to != heavySon[node]){
decomposition(to);
}
}
}
int maxPath(int node1, int node2){
int ans = 0;
while(label[node1] != label[node2]){
if(level[head[label[node1]]] > level[head[label[node2]]]){
ans = max(ans, aint.query(tin[node1], tin[head[label[node1]]]));
node1 = parent[head[label[node1]]];
}
else {
ans = max(ans, aint.query(tin[node2], tin[head[label[node2]]]));
node2 = parent[head[label[node2]]];
}
}
if(tin[node1] > tin[node2]) swap(node1, node2);
ans = max(ans, aint.query(tin[node1], tin[node2]));
return ans;
}
void solve(){
cin >> nodes >> queries;
for(int i = 1; i <= nodes; ++i){
cin >> a[i];
}
for(int i = 1; i < nodes; ++i){
int node1, node2; cin >> node1 >> node2;
adj[node1].push_back(node2);
adj[node2].push_back(node1);
}
dfs(1);
decomposition(1);
aint = nodes;
for(int i = 1; i <= nodes; ++i){
tin[i] = nodes - tin[i] + 1;
aint.update(tin[i], a[i]);
}
for(int i = 0; i < queries; ++i){
int type, x, y; cin >> type >> x >> y;
if(type == 0){
aint.update(tin[x], y);
}
else {
cout << maxPath(x, y) << '\n';
}
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
freopen(INFILE, "r", stdin);
freopen(OUTFILE, "w", stdout);
solve();
return 0;
}