Pagini recente » Cod sursa (job #397296) | Cod sursa (job #2365124) | Cod sursa (job #2550491) | Cod sursa (job #3121312) | Cod sursa (job #1208245)
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
class ST {
public:
ST(const vector<int> &values)
{
for (size = 1; size < int(values.size()); size *= 2); // size = cea mai mica putere a lui 2, mai mare decat size()
tree = vector<int>(2 * size, 0); // 4 n
for (int x = 0; x < int(values.size()); ++x) // valorile innitiale puse pe poz [n, .. 2n -1]
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 l, int r) const
{
l += size;
r += size;
int vmax = 0;
while (l <= r)
{
vmax = max(vmax, max(tree[l], tree[r]));
l = (l + 1) / 2;
r = (r - 1) / 2;
}
return vmax;
}
private:
int size;
vector<int> tree;
};
vector<vector<int> > T, paths;
int V;
vector<int> v, t, Size, h, pId, pos;
vector<ST> st;
void DFS(const int x)
{
int hs(-1);
Size[x] = 1;
for ( auto y : T[x] )
{
if (y == t[x])
continue;
t[y] = x;
h[y] = h[x] + 1;
DFS(y);
Size[x] += Size[y];
if (hs == -1 || Size[y] > Size[hs])
hs = y;
}
if (hs == -1 ) // frunza
{
pId[x] = int(paths.size());
paths.push_back(vector<int>());
}
else
pId[x] = pId[hs];
pos[x] = int(paths[pId[x]].size()); // va fi pus la sfarsit (vechea poz n)
paths[pId[x]].push_back(x);
}
void BuildHeavyPath()
{
t = pId = vector<int>(V, -1); // V e nr de noduri a arborelui
Size = vector<int>(V, 0); // Size[i] - ne nodur idin subarb cu rad in i
h = vector<int>(V, -1); // adancimea in Dfs
pos = vector<int>(V, -1); // -1 pe ce poz in lantul curent e x
h[0] = 0;
DFS(0);
for (int p = 0; p < int(paths.size()); ++p)
{
vector<int> pathValues; // putea fi pathValues(Value)
for (int x : paths[p])
pathValues.push_back(v[x]);
st.push_back(ST(pathValues));
}
}
int Query(int x, int y)
{
if (pId[x] == pId[y])
{
if (pos[x] > pos[y])
swap(x, y);
return st[pId[x]].Query(pos[x], pos[y]);
}
if (h[paths[pId[x]].back()] < h[paths[pId[y]].back()])
swap(x, y);
return max(st[pId[x]].Query(pos[x], int(paths[pId[x]].size()) - 1),
Query(t[paths[pId[x]].back()], y));
}
int main()
{
int Q;
fin >> V >> Q;
v = vector<int>(V);
for (int x = 0; x < V; ++x)
fin >> v[x];
T = vector< vector<int> >(V, vector<int>());
for (int e = 1; e < V; ++e)
{
int x, y;
fin >> x >> y;
x--, y--;
T[x].push_back(y);
T[y].push_back(x);
}
BuildHeavyPath();
int op, x, y, val;
for (; Q > 0; --Q)
{
fin >> op;
if (op == 0)
{
fin >> x >> val;
v[x] = val;
st[pId[x - 1]].Update(pos[x - 1], val);
}
else
{
fin >> x >> y;
fout << Query(x - 1, y - 1) << "\n";
}
}
fin.close();
fout.close();
return 0;
}