Pagini recente » Cod sursa (job #2134196) | Cod sursa (job #2043845) | Cod sursa (job #2692356) | Cod sursa (job #1689331) | Cod sursa (job #1177883)
#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) {
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 = size + max(from, 0);
to = size + min(to, size - 1);
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> Values, Father, Size, Level, PathIndex, PathPosition;
vector<SegmentTree> SegmentTrees;
void DFS(const int x) {
Size[x] = 1;
int heaviestSon = NIL;
for (vector<int>::const_iterator y = T[x].begin(); y != T[x].end(); ++y) {
if (*y != Father[x]) {
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() {
Father = vector<int>(V, NIL);
Size = vector<int>(V, 0);
Level = PathIndex = PathPosition = vector<int>(V, -1);
Paths = vector< vector<int> >();
Level[0] = 0;
DFS(0);
}
void BuildSegmentTrees() {
for (int i = 0; i < int(Paths.size()); ++i) {
vector<int> pathValues;
for (int j = 0; j < int(Paths[i].size()); ++j)
pathValues.push_back(Values[Paths[i][j]]);
SegmentTrees.push_back(SegmentTree(pathValues));
}
}
inline 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(Query(Father[Paths[PathIndex[x]].back()], y), SegmentTrees[PathIndex[x]].Query(PathPosition[x], int(Paths[PathIndex[x]].size()) - 1));
}
inline void AddEdge(const int x, const int y) {
T[x].push_back(y);
T[y].push_back(x);
}
int main() {
ifstream in("heavypath.in");
ofstream out("heavypath.out");
int Q;
in >> V >> Q;
Values = vector<int>(V);
for (int x = 0; x < V; ++x)
in >> Values[x];
T = vector< vector<int> >(V, vector<int>());
for (int i = 1; i < V; ++i) {
int x, y;
in >> x >> y;
AddEdge(x - 1, y - 1);
}
BuildHeavyPathDecomposition();
BuildSegmentTrees();
for (; Q > 0; --Q) {
int type;
in >> type;
if (type == 0) {
int x, v;
in >> x >> v;
SegmentTrees[PathIndex[x - 1]].Update(PathPosition[x - 1], v);
} else {
int x, y;
in >> x >> y;
out << Query(x - 1, y - 1) << "\n";
}
}
in.close();
out.close();
return 0;
}