Pagini recente » Cod sursa (job #2379703) | Cod sursa (job #2622739) | Cod sursa (job #2548222) | Cod sursa (job #2086317) | Cod sursa (job #2986805)
#include <fstream>
#include <vector>
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int n, m, i, j, v[100100], a, b, t, normn, lca, head, rasp, auxnode;
vector<int> neighbours[100100];
int heavychild[100100], tsize[100100], p[100100];
int pathroot[100100], poz[100100], depth[100100];
int segtree[280100], dsu[100100];
vector<pair<int, int>> lcaquery[100100];
bool viz[100100];
struct query
{
int t, x, y;
} queries[100100];
int dsuGetRoot(int node)
{
if (!dsu[node])
return node;
return dsu[node] = dsuGetRoot(dsu[node]);
}
void dfs1(int node)
{
tsize[node] = 1;
for (int j = 0; j < neighbours[node].size(); j++) {
if (neighbours[node][j] != p[node]) {
depth[neighbours[node][j]] = depth[node] + 1;
p[neighbours[node][j]] = node;
dfs1(neighbours[node][j]);
tsize[node] += tsize[neighbours[node][j]];
if (tsize[neighbours[node][j]] > tsize[heavychild[node]]) {
heavychild[node] = neighbours[node][j];
}
}
}
}
void heavyfirst(int node)
{
poz[node] = ++t;
segtree[normn + t - 1] = v[node];
if (heavychild[node]) {
pathroot[heavychild[node]] = pathroot[node];
heavyfirst(heavychild[node]);
for (int j = 0; j < neighbours[node].size(); j++) {
if (neighbours[node][j] != p[node] && neighbours[node][j] != heavychild[node]) {
pathroot[neighbours[node][j]] = neighbours[node][j];
heavyfirst(neighbours[node][j]);
}
}
}
}
void tarjandfs(int node)
{
viz[node] = true;
for (int j = 0; j < lcaquery[node].size(); j++) {
if (viz[lcaquery[node][j].first]) {
lcaquery[node][j].second = dsuGetRoot(lcaquery[node][j].first);
}
}
for (int j = 0; j < neighbours[node].size(); j++) {
if (!viz[neighbours[node][j]]) {
tarjandfs(neighbours[node][j]);
dsu[neighbours[node][j]] = node;
}
}
}
int segtreeQuery(int st, int dr)
{
int ans = 0;
st = normn + st - 1;
dr = normn + dr - 1;
while (st < dr) {
if ((st & 1) == 1) {
ans = max(ans, segtree[st++]);
}
if ((dr & 1) == 0) {
ans = max(ans, segtree[dr--]);
}
st >>= 1;
dr >>= 1;
}
if (st == dr)
ans = max(ans, segtree[st]);
return ans;
}
int main()
{
f >> n >> m;
for (i = 1; i <= n; i++) {
f >> v[i];
}
normn = n;
while (normn & (normn-1)) {
normn = normn + (normn & (-normn));
}
for (i = 1; i < n; i++) {
f >> a >> b;
neighbours[a].push_back(b);
neighbours[b].push_back(a);
}
depth[1] = 1;
p[1] = 0;
dfs1(1);
pathroot[1] = 1;
heavyfirst(1);
for (i = normn - 1; i >= 1; i--) {
segtree[i] = max(segtree[2*i], segtree[2*i+1]);
}
for (i = 1; i <= m; i++) {
f >> queries[i].t >> queries[i].x >> queries[i].y;
}
for (i = m; i >= 1; i--) {
if (queries[i].t == 1) {
lcaquery[queries[i].x].push_back({queries[i].y, 0});
lcaquery[queries[i].y].push_back({queries[i].x, 0});
}
}
tarjandfs(1);
for (i = 1; i <= m; i++) {
if (queries[i].t == 0) {
j = normn + poz[queries[i].x] - 1;
segtree[j] = queries[i].y;
j >>= 1;
while (j) {
segtree[j] = max(segtree[2*j], segtree[2*j+1]);
j >>= 1;
}
}
else if (queries[i].t == 1) {
rasp = 0;
lca = max(lcaquery[queries[i].x].back().second, lcaquery[queries[i].y].back().second);
lcaquery[queries[i].x].pop_back();
lcaquery[queries[i].y].pop_back();
auxnode = queries[i].x;
while (auxnode) {
head = pathroot[auxnode];
if (depth[head] > depth[lca]) {
rasp = max(rasp, segtreeQuery(poz[head], poz[auxnode]));
auxnode = p[head];
}
else {
rasp = max(rasp, segtreeQuery(poz[lca], poz[auxnode]));
auxnode = 0;
}
}
auxnode = queries[i].y;
while (auxnode) {
head = pathroot[auxnode];
if (depth[head] > depth[lca]) {
rasp = max(rasp, segtreeQuery(poz[head], poz[auxnode]));
auxnode = p[head];
}
else {
rasp = max(rasp, segtreeQuery(poz[lca], poz[auxnode]));
auxnode = 0;
}
}
g << rasp << '\n';
}
}
f.close();
g.close();
return 0;
}