Pagini recente » Cod sursa (job #1321172) | Cod sursa (job #2341845) | Cod sursa (job #460092) | Cod sursa (job #1471849) | Cod sursa (job #2733393)
#include <fstream>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");
const int N = 1e5 + 5;
int a[4 * N];
int subarb[N], lant[N], poz[N], ad[N], val[N];
int tata[N][22];
int n;
int poz_aint, start = 1;
int nrpasi = 0;
vector <int> v[N];
void dfs(int nod, int adancime) {
subarb[nod] = 1;
ad[nod] = adancime;
for (auto it : v[nod]) {
if (!subarb[it]) {
dfs(it, adancime + 1);
subarb[nod] += subarb[it];
tata[it][0] = nod;
}
}
}
bool cmp_vefini(int x, int y) {
return subarb[x] > subarb[y];
}
void create_segments(int nod, int Lant) {
a[++poz_aint] = val[nod];
poz[nod] = poz_aint; //pozitia nodului nod in aint
lant[nod] = Lant;
sort (v[nod].begin(), v[nod].end(), cmp_vefini);
bool lant_curent = true;
for (auto it : v[nod]) {
if (!poz[it]) {
if (!lant_curent)
create_segments(it, it);
else {
create_segments(it, lant[nod]);
lant_curent = false;
}
}
}
}
namespace aint {
void build() {
for (int i = start - 1; i; --i) {
a[i] = max(a[i + i], a[i + i + 1]);
}
}
void Update(int nod) {
a[nod] = max(a[nod + nod], a[nod + nod + 1]);
if (nod > 1)
Update(nod / 2);
}
int Query(int st, int dr) {
int ans = 0;
if (st & 1)
ans = a[st++];
if (!(dr & 1))
ans = max(ans, a[dr--]);
int aux = 0;
if (st < dr)
aux = Query(st / 2, dr / 2);
return max(aux, ans);
}
}
namespace stramosi {
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_daddy(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 (ad[x] > ad[y])
x = find_daddy(x, ad[x] - ad[y]);
if (ad[y] > ad[x])
y = find_daddy(y, ad[y] - ad[x]);
if (x == y)
return x;
int ans = 1;
for (int i = 19; i >= 0; --i) {
if (tata[x][i] != tata[y][i]) {
x = tata[x][i];
y = tata[y][i];
} else ans = tata[x][i];
}
return ans;
}
}
int Query(int nod, int l) {
if (lant[l] == lant[nod])
return aint::Query(poz[l], poz[nod]);
int aux = aint::Query(poz[lant[nod]], poz[nod]);
int aux2 = Query(tata[lant[nod]][0], l);
return max(aux, aux2);
}
int main() {
int m, x, y, type;
fin >> n >> m;
for (int i = 1; i <= n; ++i)
fin >> val[i];
for (int i = 1; i < n; ++i) {
fin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1, 1);
while (start < n)
start <<= 1;
poz_aint = start - 1;
create_segments(1, 1);
aint::build();
stramosi::rmq();
while (m--) {
fin >> type >> x >> y;
if (type == 0) {
a[poz[x]] = y;
aint::Update(poz[x] / 2);
} else {
int l = stramosi::lca(x, y);
// fout << Query(x, l) << ' ';
// fout << Query(y, l) << '\n';
nrpasi = 0;
int ans = Query(x, l);
int aux = Query(y, l);
// if (nrpasi > 1000)
// return l;
fout << max(ans, aux) << '\n';
}
}
return 0;
}