Pagini recente » Cod sursa (job #2109935) | Cod sursa (job #1927881) | Cod sursa (job #2054384) | Cod sursa (job #1155181) | Cod sursa (job #2349749)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
using VI = vector<int>;
using ll = long long;
using VL = vector<ll>;
using VVI = vector<VI>;
class ST{
public:
ST(const VI& val)
{
for (N = 1; N < (int)val.size(); N <<= 1);
tree = VI(2*N);
for (size_t i = 0; i < val.size(); ++i)
tree[N + i] = val[i];
for (int i = N - 1; i > 0; --i)
tree[i] = max(tree[2 * i], tree[2 * i + 1]);
}
void Update(int pos, int val)
{
pos += N;
tree[pos] = val;
for (pos >>= 1; pos > 0; pos >>= 1)
tree[pos] = max(tree[pos * 2], tree[pos * 2 + 1]);
}
int Query(int l, int r)
{
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:
VI tree;
int N;
};
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int N, M;
VI val;
VVI G;
VVI paths;
VI t, nr, h;
VI pos, pathID;
vector<ST> st;
void ReadData();
void DecomposeTree();
void DFS(int node);
int Query(int n1, int n2);
void Update(int node, int val);
int main()
{
ReadData();
DecomposeTree();
int type, x, y;
while (M--)
{
fin >> type >> x >> y;
if (type == 0)
Update(x, y);
else
fout << Query(x, y) << '\n';
}
fin.close();
fout.close();
return 0;
}
void ReadData()
{
fin >> N >> M;
h = pathID = nr = t = pos = val = VI(N + 1);
G = VVI(N + 1);
for (int i = 1; i <= N; ++i)
fin >> val[i];
int x, y;
for (int i = 1; i < N; ++i)
{
fin >> x >> y;
G[x].push_back(y);
G[y].push_back(x);
}
}
void DecomposeTree()
{
DFS(1);
for (const VI& path : paths)
{
VI pathValues;
for (const int& node : path)
pathValues.push_back(val[node]);
st.push_back(ST(pathValues));
}
}
void DFS(int node)
{
int son{-1};
nr[node] = 1;
for (const int& next : G[node])
{
if (next == t[node])
continue;
t[next] = node;
DFS(next);
h[next] = h[node] + 1;
nr[node] += nr[next];
if (son == -1 || nr[son] < nr[next])
son = next;
}
if (son == -1)
{
pathID[node] = paths.size();
paths.push_back(VI());
}
else
pathID[node] = pathID[son];
paths[pathID[node]].push_back(node);
pos[node] = (int)paths[pathID[node]].size() - 1;
}
int Query(int n1, int n2)
{
if (pathID[n1] == pathID[n2])
{
if (pos[n1] > pos[n2])
swap(n1, n2);
return st[pathID[n1]].Query(pos[n1], pos[n2]);
}
if ( h[paths[pathID[n1]].back()] < h[paths[pathID[n2]].back()] )
swap(n1, n2);
return max(st[pathID[n1]].Query(pos[n1], (int)paths[pathID[n1]].size() - 1),
Query(t[paths[pathID[n1]].back()], n2));
}
void Update(int node, int val)
{
st[pathID[node]].Update(pos[node], val);
}