Pagini recente » Cod sursa (job #903310) | Cod sursa (job #2872862) | Cod sursa (job #1038439) | Cod sursa (job #724272) | Cod sursa (job #1198682)
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
const int NIL = -1;
class SegmentTree {
public:
SegmentTree(const vector<int> &values):
size(1),
tree(vector<int>()) {
for (; size < int(values.size()); size *= 2);
tree = vector<int>(2 * size, 0);
for (int x = 0; x < int(values.size()); ++x)
tree[size + x] = values[x];
for (int x = size - 1; x > 0; --x)
tree[x] = max(tree[2 * x], tree[2 * x + 1]);
}
void Update(int where, const int value) {
if (where < 0 || where >= size)
return;
tree[where += size] = value;
for (where /= 2; where > 0; where /= 2)
tree[where] = max(tree[2 * where], tree[2 * where + 1]);
}
int Query(int from, int to) const {
from = max(0, from);
to = min(size - 1, to);
if (from > to)
return 0;
from += size;
to += size;
int maxValue = 0;
while (from <= to) {
maxValue = max(maxValue, max(tree[from], tree[to]));
from = (from + 1) / 2;
to = (to - 1) / 2;
}
return maxValue;
}
private:
int size;
vector<int> tree;
};
vector< vector<int> > T, Paths;
int V;
vector<int> Value, Father, Size, Level, PathIndex, PathPosition;
vector<SegmentTree> SegmentTrees;
void DFS(const int x) {
int heaviestSon = NIL;
Size[x] = 1;
for (vector<int>::const_iterator y = T[x].begin(); y != T[x].end(); ++y) {
if (*y == Father[x])
continue;
Father[*y] = x;
Level[*y] = Level[x] + 1;
DFS(*y);
Size[x] += Size[*y];
if (heaviestSon == NIL || Size[*y] > Size[heaviestSon])
heaviestSon = *y;
}
if (heaviestSon == NIL) {
PathIndex[x] = int(Paths.size());
Paths.push_back(vector<int>());
} else {
PathIndex[x] = PathIndex[heaviestSon];
}
PathPosition[x] = int(Paths[PathIndex[x]].size());
Paths[PathIndex[x]].push_back(x);
}
void BuildHeavyPathDecomposition() {
Paths = vector< vector<int> >();
Father = PathIndex = vector<int>(V, NIL);
Size = vector<int>(V, 0);
Level = vector<int>(V, -1);
PathPosition = vector<int>(V, -1);
Level[0] = 0;
DFS(0);
for (int p = 0; p < int(Paths.size()); ++p) {
vector<int> pathValues;
for (vector<int>::const_iterator x = Paths[p].begin(); x != Paths[p].end(); ++x)
pathValues.push_back(Value[*x]);
SegmentTrees.push_back(SegmentTree(pathValues));
}
}
int Query(int x, int y) {
if (PathIndex[x] == PathIndex[y]) {
if (PathPosition[x] > PathPosition[y])
swap(x, y);
return SegmentTrees[PathIndex[x]].Query(PathPosition[x], PathPosition[y]);
}
if (Level[Paths[PathIndex[x]].back()] < Level[Paths[PathIndex[y]].back()])
swap(x, y);
return max(SegmentTrees[PathIndex[x]].Query(PathPosition[x], int(Paths[PathIndex[x]].size()) - 1), Query(Father[Paths[PathIndex[x]].back()], y));
}
inline void AddEdge(const int x, const int y) {
T[x].push_back(y);
T[y].push_back(x);
}
int main() {
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
int Q;
cin >> V >> Q;
Value = vector<int>(V);
for (int x = 0; x < V; ++x)
cin >> Value[x];
T = vector< vector<int> >(V, vector<int>());
for (int e = 1; e < V; ++e) {
int x, y;
cin >> x >> y;
AddEdge(x - 1, y - 1);
}
BuildHeavyPathDecomposition();
for (; Q > 0; --Q) {
int type;
cin >> type;
if (type == 0) {
int x, value;
cin >> x >> value;
Value[x] = value;
SegmentTrees[PathIndex[x - 1]].Update(PathPosition[x - 1], value);
} else {
int x, y;
cin >> x >> y;
cout << Query(x - 1, y - 1) << "\n";
}
}
cin.close();
cout.close();
return 0;
}