Pagini recente » Cod sursa (job #2958281) | Cod sursa (job #564498) | Cod sursa (job #1636477) | Cod sursa (job #708371) | Cod sursa (job #1632193)
#include <fstream>
#include <iostream>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;
ifstream is("heavypath.in");
ofstream os("heavypath.out");
using VI = vector<int>;
using VVI = vector<VI>;
class AIB{
public:
AIB(const VI &v)
{
n = v.size();
for ( N = 1; N < n; N <<= 1 );
arb = VI(2 * N);
for ( int i = 0; i < n; ++i )
arb[i + N] = v[i];
for ( int i = N - 1; i; --i )
arb[i] = max(arb[2 * i], arb[2 * i + 1]);
}
void update(int poz, int val)
{
arb[poz += N] = val;
for ( poz >>= 1; poz; poz >>= 1 )
arb[poz] = max(arb[2 * poz], arb[2 * poz + 1]);
}
int query(int st, int dr)
{
st += N;
dr += N;
int answ = 0;
while ( st <= dr )
{
answ = max(answ, max(arb[st], arb[dr]));
st = ( st + 1 ) >> 1;
dr = ( dr - 1 ) >> 1;
}
return answ;
}
private:
int n, N;
VI arb;
};
int n, m;
VI v, grup, poz, t, h, nr;
VVI g, paths;
vector<AIB> a;
void Read();
void Build();
void DF(int nod);
int Query(int x, int y);
int main()
{
Read();
Build();
int tip, x, y;
while ( m-- )
{
is >> tip >> x >> y;
if ( !tip )
a[grup[x]].update(poz[x], y);
else
os << Query(x, y) << "\n";
}
is.close();
os.close();
return 0;
}
int Query(int x, int y)
{
if ( grup[x] == grup[y] )
{
if ( poz[x] > poz[y] )
swap(x, y);
return a[grup[x]].query(poz[x], poz[y]);
}
if ( h[paths[grup[x]].back()] < h[paths[grup[y]].back()] )
swap(x, y);
return max(a[grup[x]].query(poz[x], paths[grup[x]].size() - 1), Query(t[paths[grup[x]].back()], y));
}
void Build()
{
grup = poz = t = h = nr = VI(n + 1);
DF(1);
VI aux;
for ( const auto &i : paths )
{
aux.clear();
for ( const auto &j : i )
aux.push_back(v[j]);
a.push_back(aux);
}
}
void DF(int nod)
{
int hs = 0;
nr[nod] = 1;
for ( const auto &nodv : g[nod] )
if ( !nr[nodv] )
{
t[nodv] = nod;
h[nodv] = h[nod] + 1;
DF(nodv);
nr[nod] += nr[nodv];
if ( nr[nodv] > nr[hs] )
hs = nodv;
}
if ( !hs )
{
grup[nod] = paths.size();
paths.push_back(VI(1, nod));
return;
}
grup[nod] = grup[hs];
poz[nod] = paths[grup[nod]].size();
paths[grup[nod]].push_back(nod);
}
void Read()
{
is >> n >> m;
v = VI(n + 1);
for ( int i = 1; i <= n; ++i )
is >> v[i];
int x, y;
g = VVI(n + 1);
for ( int i = 1; i < n; ++i )
{
is >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
}