Pagini recente » Cod sursa (job #3234573) | Cod sursa (job #2269806) | Cod sursa (job #3244722) | Cod sursa (job #3201510) | Cod sursa (job #2739171)
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
class InParser
{
#pragma warning(disable:4996)
private:
FILE* fin;
char* buff;
int sp;
char read()
{
++sp;
if (sp == 4096)
{
sp = 0;
fread(buff, 1, 4096, fin);
}
return buff[sp];
}
public:
InParser(const char* nume)
{
sp = 4095;
buff = new char[4096];
fin = fopen(nume, "r");
}
InParser& operator >> (int& n)
{
int sgn = 1;
char c;
while (!isdigit(c = read()) && c != '-');
if (c == '-')
{
n = 0;
sgn = -1;
}
else
n = c - '0';
while (isdigit(c = read()))
n = n * 10 + c - '0';
n *= sgn;
return *this;
}
};
InParser fin("heavypath.in");
ofstream fout("heavypath.out");
using VI = vector<int>;
using VVI = vector<VI>;
class ST {
public:
ST(const VI& values)
{
for (N = 1; N < int(values.size()); N <<= 1);
tree = VI(2 * N, 0);
for (size_t i = 0; i < values.size(); ++i)
tree[N + i] = values[i];
for (int x = N - 1; x > 0; --x)
tree[x] = max(tree[2 * x], tree[2 * x + 1]);
}
void Update(int where, const int value)
{
tree[where += N] = value;
for (where >>= 1; where > 0; where >>= 1)
tree[where] = max(tree[2 * where], tree[2 * where + 1]);
}
int Query(int l, int r) const
{
l += N; r += N;
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 N;
VI tree;
};
VVI T, paths;
int N;
VI v, t, nr, h, hmin, pId, pos;
vector<ST> st;
void DFS(const int x)
{
int hs(0);
nr[x] = 1;
for (const auto& y : T[x])
{
if (y == t[x])
continue;
t[y] = x;
h[y] = h[x] + 1;
DFS(y);
nr[x] += nr[y];
if (hs == 0 || nr[y] > nr[hs])
hs = y;
}
if (hs == 0)
{
pId[x] = int(paths.size());
paths.push_back(vector<int>());
}
else
pId[x] = pId[hs];
pos[x] = int(paths[pId[x]].size());
paths[pId[x]].push_back(x);
}
void BuildHeavyPath()
{
t = pId = nr = h = pos = VI(N + 1);
DFS(1);
hmin = vector<int>(paths.size() + 1);
for (size_t p = 0; p < paths.size(); ++p)
{
vector<int> pathValues;
hmin[p] = h[paths[p].back()];
for (const 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 (hmin[pId[x]] < hmin[pId[y]])
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 >> N >> Q;
v = VI(N + 1);
T = VVI(N + 1);
for (int x = 1; x <= N; ++x)
fin >> v[x];
for (int e = 1; e < N; ++e)
{
int x, y;
fin >> 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]].Update(pos[x], val);
}
else
{
fin >> x >> y;
fout << Query(x, y) << "\n";
}
}
fout.close();
return 0;
}