Pagini recente » Cod sursa (job #2637479) | Cod sursa (job #1383581) | Cod sursa (job #114176) | Cod sursa (job #264653) | Cod sursa (job #1969648)
#include <bits/stdc++.h>
using namespace std;
#define REP(i,a) for (int i = 0; i < a; i++)
#define FOR(i,a,b) for (int i = a; i <= b; i++)
#define ROF(i,a,b) for (int i = a; i >= b; i--)
#define FOREACH(it,x) for (auto it: (x))
#define pb push_back
#define SZ(x) ((int)(x).size())
const int Nmax = 100000;
int n,m;
int weight[Nmax+1];
int data[Nmax*2+5];
int val[Nmax+1];
vector<int> G[Nmax+1];
vector< vector<int> > chain;
int what_chain[Nmax+1];
int pos_in_chain[Nmax+1];
int pos_in_aint[Nmax+1];
int T[Nmax+1];
int lvl[Nmax+1];
void dfs(int node,int parent)
{
weight[node] = 1;
int best = -1;
FOREACH(it,G[node]) if (it != parent) {
lvl[it] = lvl[node] + 1; T[it] = node; dfs(it,node);
weight[node] += weight[it];
if (best == -1 || weight[best] < weight[it]) best = it;
}
if (best == -1) {
chain.pb(vector<int>());
chain.back().pb(node);
what_chain[node] = SZ(chain) - 1;
pos_in_chain[node] = 0;
}
else {
chain[what_chain[best]].pb(node);
what_chain[node] = what_chain[best];
pos_in_chain[node] = SZ(chain[what_chain[best]]) - 1;
}
}
void buildTree() {
for (int p = n - 1; p > 0; p--)
data[p] = max(data[p<<1],data[p<<1|1]);
}
void update(int pos,int value) {
pos += n; data[pos] = value;
for (; pos > 1; pos >>= 1)
data[pos>>1] = max(data[pos],data[pos^1]);
}
int query(int l,int r) {
int ret = 0;
for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
if (l&1)
ret = max(ret,data[l++]);
if (r&1)
ret = max(ret,data[--r]);
}
return ret;
}
void buildHPD()
{
lvl[1] = 0;
dfs(1,-1);
int cpos = 0;
REP(i,SZ(chain)) {
REP(j,SZ(chain[i])) {
pos_in_aint[chain[i][j]] = cpos;
data[cpos+n] = val[chain[i][j]];
++cpos;
}
}
buildTree();
}
int QueryHPD(int x,int y)
{
int ret = 0;
while (what_chain[x] != what_chain[y]) {
if (lvl[chain[what_chain[x]].back()] < lvl[chain[what_chain[y]].back()]) swap(x,y);
ret = max(ret,query(pos_in_aint[x],pos_in_aint[chain[what_chain[x]].back()]));
x = T[chain[what_chain[x]].back()];
}
if (pos_in_aint[x] > pos_in_aint[y]) swap(x,y);
return max(ret,query(pos_in_aint[x],pos_in_aint[y]));
}
int main()
{
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
fin >> n >> m;
FOR(i,1,n) fin >> val[i];
FOR(i,1,n-1) {
int x,y;
fin >> x >> y;
G[x].pb(y),G[y].pb(x);
}
buildHPD();
FOR(i,1,m) {
int t,x,y; fin >> t >> x >> y;
if (t == 0) update(pos_in_aint[x],y);
else fout << QueryHPD(x,y) << "\n";
}
}