Pagini recente » Cod sursa (job #1446725) | Cod sursa (job #121700) | Cod sursa (job #1700465) | Cod sursa (job #1852864) | Cod sursa (job #2271255)
#include <cstdio>
#include <algorithm>
#include <vector>
const int MAX_N = 100000;
class SegmentTree {
public:
int value;
int leftIndex;
int rightIndex;
SegmentTree* left;
SegmentTree* right;
void build(int nodeLeft, int nodeRight) {
leftIndex = nodeLeft;
rightIndex = nodeRight;
int mid = (nodeLeft + nodeRight) >> 1;
if (leftIndex != rightIndex) {
left = new SegmentTree;
left->build(nodeLeft, mid);
right = new SegmentTree;
right->build(mid + 1, nodeRight);
}
}
void update(int pos, int newValue) {
if (leftIndex == rightIndex)
value = newValue;
else {
int mid = (leftIndex + rightIndex) >> 1;
if (pos <= mid)
left->update(pos, newValue);
else
right->update(pos, newValue);
value = std::max(left->value, right->value);
}
}
int query(int qLeft, int qRight) {
if (qLeft <= leftIndex && rightIndex <= qRight)
return value;
else {
int mid = (leftIndex + rightIndex) >> 1;
int ans = 0;
if (qLeft <= mid)
ans = std::max(ans, left->query(qLeft, qRight));
if (qRight > mid)
ans = std::max(ans, right->query(qLeft, qRight));
return ans;
}
}
};
struct Chain {
int left;
//int right;
int dad;
Chain() {
left = dad = 0;
}
};
int a[1 + MAX_N];
int treeSize[1 + MAX_N];
int depth[1 + MAX_N];
int heavySon[1 + MAX_N];
std::vector<int> g[1 + MAX_N];
std::vector<int> heavyPath;
int chainId[1 + MAX_N];
int chains;
Chain chain[1 + MAX_N];
int posHeavy[1 + MAX_N];
bool viz[1 + MAX_N];
SegmentTree* root = new SegmentTree;
void dfsSize(int v) {
viz[v] = true;
treeSize[v] = 1;
//depth[v] = depth[dad] + 1;
//int biggestSonSize = 0;
for (auto u : g[v]) {
if (!viz[u]) {
depth[u] = depth[v] + 1;
dfsSize(u);
treeSize[v] += treeSize[u];
if (treeSize[heavySon[v]] < treeSize[u])
heavySon[v] = u;
}
}
}
void dfsHeavy(int v, int dad) {
heavyPath.push_back(v);
posHeavy[v] = (int)heavyPath.size();
if (heavySon[dad] == v) {
chainId[v] = chainId[dad];
}
else {
chainId[v] = ++chains;
chain[chains].left = (int)heavyPath.size();
chain[chains].dad = dad;
}
//chain[chainId[v]].right = (int)heavyPath.size();
if (heavySon[v] != 0) {
dfsHeavy(heavySon[v], v);
for (auto u : g[v]) {
if (u != dad && u != heavySon[v])
dfsHeavy(u, v);
}
}
}
int pathMax(int u, int v) {
if (chainId[u] == chainId[v])
return root->query(std::min(posHeavy[u], posHeavy[v]), std::max(posHeavy[u], posHeavy[v]));
else {
if (depth[chain[chainId[u]].dad] < depth[chain[chainId[v]].dad])
std::swap(u, v);
int tempAns = root->query(chain[chainId[u]].left, posHeavy[u]);
return std::max(tempAns, pathMax(chain[chainId[u]].dad, v));
}
}
int main() {
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= n - 1; i++) {
int v, u;
scanf("%d%d", &v, &u);
g[v].push_back(u);
g[u].push_back(v);
}
depth[1] = 1;
dfsSize(1);
for (int i = 1; i <= n; i++)
viz[i] = false;
dfsHeavy(1, 0);
root->build(1, n);
int pos = 0;
for (auto it : heavyPath)
root->update(++pos, a[it]);
for (int i = 1; i <= m; i++) {
int t, x, y;
scanf("%d%d%d", &t, &x, &y);
if (t == 0)
root->update(posHeavy[x], y);
else
printf("%d\n", pathMax(x, y));
}
return 0;
}