Pagini recente » Cod sursa (job #2346075) | Cod sursa (job #941240) | Cod sursa (job #2580139) | Cod sursa (job #2535852) | Cod sursa (job #1182941)
#include <fstream>
#include <vector>
using namespace std;
const int N = 1 + 1e5;
vector<int> tree[N];
int T[N], son[N], head[N], stramos[N], succesor[N], n;
int heavyDepth[N], depth[N];
int cost[N], jmpCost[N];
int stack[N], level[N];
inline int lsb(int x){
return x & -x;
}
void mark(int x, int lvl, int D){
stack[lvl] = x;
level[x] = lvl;
head[x] = stack[1];
heavyDepth[x] = D;
if (son[x])
mark(son[x], lvl + 1, D);
else
for (int i = 1 ; i <= lvl ; i++){
stramos[ stack[i] ] = stack[i - lsb(i)];
succesor[ stack[i] ] = stack[i + lsb(i)];
}
for (auto it = tree[x].begin() ; it != tree[x].end() ; it++)
if (son[x] != *it && *it != T[x]){
stack[0] = x;
mark(*it, 1, 1 + heavyDepth[x]);
}
}
int dfs(int x, int father){
int weight = 1, val, bestVal = -1;
T[x] = father;
depth[x] = 1 + depth[father];
for (auto it = tree[x].begin() ; it != tree[x].end() ; it++)
if ( *it != father ){
weight += val = dfs(*it, x);
if (bestVal < val){
bestVal = val;
son[x] = *it;
}
}
return weight;
}
int pathQuery(int x, int y){ ///x trebuie sa fie mai jos ca y
int ans = 0;
while (x != y)
if ( depth[y] <= depth[ stramos[x] ] ){
ans = max(ans, jmpCost[x]);
x = stramos[x];
} else {
ans = max(ans, cost[x]);
x = T[x];
}
return ans;
}
void update(int x, int val){
cost[x] = val;
for (int i = x ; i ; i = succesor[i])
jmpCost[i] = max( cost[i], pathQuery( T[i], stramos[i] ) );
}
void build(){
dfs(1, 0);
mark(1, 1, 1);
for (int i = 1 ; i <= n ; i++)
update(i, cost[i]);
}
int lca(int x, int y){
while ( heavyDepth[x] < heavyDepth[y] )
y = T[ head[y] ];
while ( heavyDepth[y] < heavyDepth[x] )
x = T[ head[x] ];
while (head[x] != head[y]){
x = T[ head[x] ];
y = T[ head[y] ];
}
return depth[x] < depth[y] ? x : y;
}
int query(int x, int y){
int L = lca(x, y);
return max( max( pathQuery(x, L), pathQuery(y, L) ), cost[L] );
}
int main(){
int nrQ, tip, x, y;
ifstream in("heavypath.in");
in >> n >> nrQ;
for (int i = 1 ; i <= n ; i++)
in >> cost[i];
for (int i = 1 ; i < n ; i++){
in >> x >> y;
tree[x].push_back(y);
tree[y].push_back(x);
}
build();
ofstream out("heavypath.out");
while (nrQ--){
in >> tip >> x >> y;
if (tip == 0)
update(x, y);
else
out << query(x, y) << '\n';
}
in.close();
out.close();
return 0;
}