Mai intai trebuie sa te autentifici.
Cod sursa(job #2206502)
Utilizator | Data | 22 mai 2018 19:34:20 | |
---|---|---|---|
Problema | Heavy Path Decomposition | Scor | 100 |
Compilator | cpp | Status | done |
Runda | Arhiva educationala | Marime | 3 kb |
#include <bits/stdc++.h>
#define dbg(x) cerr<<#x": "<<x<<"\n"
#define dbg_p(x) //cerr<<#x": "<<x.first<<","<<x.second<<"\n"
#define dbg_v(x, n) do{cerr<<#x"[]: ";for(int _=0;_<n;++_)cerr<<x[_]<<" ";cerr<<'\n';}while(0)
#define dbg_ok //cerr<<"OK!\n"
using namespace std;
const int N = 100100;
int n, k, nrl, lvl[N], size[N], a, b, lant[N], first[N], pos[N], q, tata[N], vals[N], lsz[N];
bool use[N];
vector <int> v[N];
template<class T>
ostream& operator<<(ostream& out, vector<T> v) {
out << v.size() << '\n';
for(auto e : v) out << e << ' ';
return out;
}
class SegmentTree {
public:
int * v, n;
SegmentTree() {
}
int que(int node, int l, int r, int x, int y) {
if(x <= l && r <= y)
return v[node];
if(r < x || l > y)
return 0;
int mid = (l + r) / 2;
return max(que(2 * node, l, mid, x, y), que(2 * node + 1, mid + 1, r, x, y));
}
void upd(int node, int l, int r, int pos, int val) {
if(l == r)
v[node] = val;
else {
int mid = (l + r) / 2;
if(pos <= mid) upd(2 * node, l, mid, pos, val);
else upd(2 * node + 1, mid + 1, r, pos, val);
v[node] = max(v[node * 2], v[2 * node + 1]);
}
}
void update(int pos, int val) {
upd(1, 0, n, pos, val);
}
int query(int a, int b) {
return que(1, 0, n, a, b);
}
}st[N / 2];
void dfs1(int k, int lv, int t) {
tata[k] = t;
use[k] = 1;
size[k] = 1;
lvl[k] = lv;
for(auto i : v[k]) {
if(use[i]) continue;
dfs1(i, lv + 1, k);
size[k] += size[i];
}
}
void dfs2(int k, int lant_k) {
use[k] = 1;
lant[k] = lant_k;
pos[k] = lsz[lant_k];
lsz[lant_k]++;
if(!first[lant_k])
first[lant_k] = k;
int szmax = 0, index = -1;
for(auto i : v[k])
if(!use[i] && size[i] > szmax) {
szmax = size[i];
index = i;
}
for(auto i : v[k]) {
if(use[i]) continue;
if(i == index) dfs2(i, lant_k);
else dfs2(i, nrl++);
}
}
int solve(int a, int b) {
if(a == -1) a = 1;
if(lant[a] == lant[b])
return st[lant[a]].query(min(pos[a], pos[b]), max(pos[b], pos[a]));
if(lvl[first[lant[a]]] < lvl[first[lant[b]]]) swap(a, b);
return max(st[lant[a]].query(0, pos[a]), solve(tata[first[lant[a]]], b));
}
int main() {
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
// freopen("heavypath.in", "r", stdin);
// freopen("heavypath.out", "w", stdout);
ios_base::sync_with_stdio(false);
cin >> n >> q;
for(int i = 1; i <= n; i++)
cin >> vals[i];
for(int i = 1; i < n; i++) {
cin >> a >> b;
v[a].push_back(b);
v[b].push_back(a);
}
dfs1(1, 1, -1);
memset(use, 0, sizeof use);
dfs2(1, nrl++);
for(int i = 0; i < nrl; i++){
st[i].v = new int[4 * lsz[i] + 60];
memset(st[i].v, 0, (4 * lsz[i] + 60) * sizeof(int));
st[i].n = lsz[i];
}
// dbg_v(vals, n + 1);
// dbg_v(lant, n + 1);
// dbg_v(pos, n + 1);
for(int i = 1; i <= n; i++)
st[lant[i]].update(pos[i], vals[i]);
// cin >> q;
int op;
for(int i = 1; i <= q; i++) {
cin >> op >> a >> b;
// dbg(a);
// dbg(b);
// dbg_ok;
if(op == 0)
st[lant[a]].update(pos[a], b);
else {
int ans = 0;
cout << solve(a, b) << '\n';
}
}
}