Pagini recente » Cod sursa (job #1246830) | Cod sursa (job #1654993) | Cod sursa (job #2155021) | Cod sursa (job #303296) | Cod sursa (job #2663965)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");
const int MAXN = 1e5 + 5;
int n, k;
int subarb[MAXN], val[MAXN];
int poz[MAXN]; ///pozitia nodului i din arbore in aint
int adancime[MAXN];
int tata[MAXN][20];
vector <int> vecin[MAXN];
struct aint {
int nod, lant;
} a[4 * MAXN];
bool cmp_vecini(int x, int y) {
return subarb[x] > subarb[y];
}
void dfs(int nod) {
subarb[nod] = 1;
for (auto it : vecin[nod]) {
if (!subarb[it]) {
adancime[it] = adancime[nod] + 1;
tata[it][0] = nod;
dfs(it);
subarb[nod] += subarb[it];
}
}
}
void Update_aint(int nod) {
if (val[a[nod + nod].nod] > val[a[nod + nod + 1].nod])
a[nod].nod = a[nod + nod].nod;
else a[nod].nod = a[nod + nod + 1].nod;
if (nod > 1)
Update_aint(nod / 2);
}
int Query_aint(int st, int dr) {
int ans = 0;
if (st & 1)
ans = val[a[st++].nod];
if (!(dr & 1)) {
ans = max(ans, val[a[dr].nod]);
--dr;
}
if (st > dr)
return ans;
int aux = Query_aint(st / 2, dr / 2);
return max(aux, ans);
}
void create_segments(int nod, int lant) {
a[++k] = {nod, lant};
poz[nod] = k;
Update_aint(k / 2);
bool acelasi_lant = true;
for (auto it : vecin[nod]) {
if (it == tata[nod][0])
continue;
if (acelasi_lant) {
create_segments(it, lant);
acelasi_lant = false;
} else create_segments(it, it);
}
}
void rmq() {
for (int i = 1; i < 20; ++i) {
for (int j = 1; j <= n; ++j) {
tata[j][i] = tata[tata[j][i - 1]][i - 1];
}
}
}
int find_tata(int nod, int nivel) {
for (int i = 1, j = 0; i <= nivel; i <<= 1, ++j)
if (i & nivel)
nod = tata[nod][j];
return nod;
}
int lca(int x, int y) {
if (adancime[y] > adancime[x])
swap(x, y);
x = find_tata(x, adancime[x] - adancime[y]);
if (x == y)
return x;
int ans = 1;
for (int i = 19; i >= 0; --i) {
if (tata[x][i] == tata[y][i])
ans = tata[x][i];
else {
x = tata[x][i];
y = tata[y][i];
}
}
return ans;
}
int Query(int nod, int l) {
int st = poz[nod];
int dr = max(poz[l], poz[a[st].lant]);
int ans = Query_aint(dr, st);
if (adancime[a[dr].lant] <= adancime[l])
return ans;
int aux = Query(tata[a[dr].lant][0], l);
return max(aux, ans);
}
int main() {
int Q, nod1, nod2, start = 1;
fin >> n >> Q;
while (start < n)
start <<= 1;
for (int i = 1; i <= n; ++i)
fin >> val[i];
for (int i = 1; i < n; ++i) {
fin >> nod1 >> nod2;
vecin[nod1].push_back(nod2);
vecin[nod2].push_back(nod1);
}
adancime[1] = 1;
dfs(1);
rmq();
for (int i = 1; i <= n; ++i)
sort(vecin[i].begin(), vecin[i].end(), cmp_vecini);
k = start - 1;
create_segments(1, 1);
int type, x, y;
while (Q--) {
fin >> type >> x >> y;
if (type == 0) {
val[x] = y;
Update_aint(poz[x] / 2);
} else {
int l = lca(x, y);
int ans = Query(x, l);
int aux = Query(y, l);
fout << max(ans, aux) << '\n';
}
}
return 0;
}