Pagini recente » Cod sursa (job #1153049) | Cod sursa (job #900613) | Cod sursa (job #409830) | Cod sursa (job #3030938) | Cod sursa (job #1550538)
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 100000;
const int NIL = -1;
const int BUFFSIZE = 65536;
inline char getChar()
{
static char buff[BUFFSIZE];
static int pos = BUFFSIZE;
if (pos == BUFFSIZE)
{
fread_unlocked(buff, 1, BUFFSIZE, stdin);
pos = 0;
}
return buff[pos++];
}
inline int readInt()
{
register int q = 0;
char c;
do
{
c = getChar();
} while (!isdigit(c));
do
{
q = (q << 1) + (q << 3) + (c - '0');
c = getChar();
} while (isdigit(c));
return q;
}
struct Edge
{
int v;
int next;
};
Edge l[2 * MAX_N - 2];
int head[MAX_N];
int key[MAX_N];
// HPD
int parent[MAX_N];
int heavy[MAX_N];
int depth[MAX_N];
int root[MAX_N];
int treePos[MAX_N];
int T[2 * MAX_N];
int N;
void addEdge(int u, int v, int pos)
{
l[pos].v = v;
l[pos].next = head[u];
head[u] = pos;
}
int DFS(int u)
{
int currSize = 1, maxSubTree = 0;
for (int i = head[u]; i != NIL; i = l[i].next)
{
int v = l[i].v;
if (parent[u] != v)
{
parent[v] = u;
depth[v] = depth[u] + 1;
int subTree = DFS(v);
if (subTree > maxSubTree)
{
heavy[u] = v;
maxSubTree = subTree;
}
currSize += subTree;
}
}
return currSize;
}
void buildHPD(int N)
{
int ptr = 0;
depth[0] = 0;
DFS(0);
for (int i = 0; i < N; i++)
{
if (heavy[parent[i]] != i)
{
for (int j = i; j != NIL; j = heavy[j])
{
root[j] = i;
T[N + ptr] = key[j];
treePos[j] = ptr++;
}
}
}
for (int i = N - 1; i > 0; i--)
T[i] = max(T[2 * i], T[2 * i + 1]);
}
int segQuery(int u, int v) // [u, v]
{
int q = 0;
u += N;
v += N + 1;
while (u < v)
{
if (u & 1)
q = max(q, T[u++]);
if (v & 1)
q = max(q, T[--v]);
u >>= 1;
v >>= 1;
}
return q;
}
void segUpdate(int u, int newKey)
{
int q;
u += N;
T[u] = newKey;
while (u > 1)
{
q = u / 2;
T[q] = max(T[u], T[u ^ 1]);
u = q;
}
}
int queryPath(int u, int v)
{
int q = 0;
while (root[u] != root[v])
{
if (depth[root[u]] > depth[root[v]])
swap(u, v);
q = max(q, segQuery(treePos[root[v]], treePos[v]));
v = parent[root[v]];
}
if (depth[u] > depth[v])
swap(u, v);
q = max(q, segQuery(treePos[u], treePos[v]));
return q;
}
int main()
{
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
int M;
int u, v;
N = readInt(); M = readInt();
for (int i = 0; i < N; i++)
{
head[i] = NIL;
heavy[i] = NIL;
key[i] = readInt();
}
for (int i = 0; i < N - 1; i++)
{
u = readInt() - 1; v = readInt() - 1;
addEdge(u, v, 2 * i);
addEdge(v, u, 2 * i + 1);
}
buildHPD(N);
while (M--)
{
int opType = readInt();
u = readInt(); v = readInt();
if (opType)
printf("%d\n", queryPath(u - 1, v - 1));
else
segUpdate(treePos[u - 1], v);
}
return 0;
}