Nu aveti permisiuni pentru a descarca fisierul grader_test5.in
Cod sursa(job #1414440)
Utilizator | Data | 2 aprilie 2015 16:56:35 | |
---|---|---|---|
Problema | Heavy Path Decomposition | Scor | 100 |
Compilator | cpp | Status | done |
Runda | Arhiva educationala | Marime | 2.94 kb |
#include <cstring>
#include <fstream>
#include <algorithm>
using namespace std;
int N, M;
int A[100002];
vector<int> V[100002];
bool S[100002];
int ARB[4 * 100002], Ap, A1, A2, Av;
int comp[100002], where[100002], what[100002];
int L1[100002], L2[100002], niv[100002];
int W[100002], T[100002], rT[100002];
int ST[100002];
void setall(int nod, int i1, int i2)
{
if (i1 == i2)
{
ARB[nod] = A[what[i1]];
return;
}
int mid = (i1 + i2) / 2;
setall(nod * 2, i1, mid);
setall(nod * 2 + 1, mid + 1, i2);
ARB[nod] = max(ARB[nod * 2], ARB[nod * 2 + 1]);
}
void update(int nod, int i1, int i2)
{
if (i1 == i2)
{
ARB[nod] = A[what[i1]];
return;
}
int mid = (i1 + i2) / 2;
if (Ap <= mid) update(nod * 2, i1, mid);
else update(nod * 2 + 1, mid + 1, i2);
ARB[nod] = max(ARB[nod * 2], ARB[nod * 2 + 1]);
}
void query(int nod, int i1, int i2)
{
if (A1 <= i1 && i2 <= A2)
{
Av = max(Av, ARB[nod]);
return;
}
int mid = (i1 + i2) / 2;
if (A1 <= mid) query(nod * 2, i1, mid);
if (A2 > mid) query(nod * 2 + 1, mid + 1, i2);
}
void preDfs(int x)
{
S[x] = true;
W[x] = 1;
T[x] = x;
for (auto nod : V[x])
if (!S[nod])
{
rT[nod] = x;
niv[nod] = niv[x] + 1;
preDfs(nod);
W[x] += W[nod];
}
}
void Dfs(int x)
{
S[x] = true;
ST[++ST[0]] = x;
for (auto nod : V[x])
if (!S[nod] && 2 * W[nod] > W[x] - 1)
T[nod] = x;
for (auto nod : V[x])
if (!S[nod])
Dfs(nod);
if (T[x] == x)
{
++comp[0];
L1[comp[0]] = where[0] + 1;
L2[comp[0]] = where[0];
while (true)
{
comp[ST[ST[0]]] = comp[0];
where[ST[ST[0]]] = ++where[0];
what[where[0]] = ST[ST[0]];
++L2[comp[0]];
--ST[0];
if (ST[ST[0] + 1] == x) break;
}
}
}
int queryARB(int nod1, int nod2)
{
if (comp[nod1] == comp[nod2])
{
A1 = where[nod1], A2 = where[nod2], Av = 0;
if (A1 > A2) swap(A1, A2);
query(1, 1, N);
return Av;
}
if (niv[rT[what[L2[comp[nod1]]]]] > niv[rT[what[L2[comp[nod2]]]]])
{
A1 = where[nod1], A2 = L2[comp[nod1]], Av = 0;
if (A2 > A2) swap(A1, A2);
query(1, 1, N);
int val = Av;
return max(val, queryARB(rT[what[L2[comp[nod1]]]], nod2));
}
else
{
A1 = where[nod2], A2 = L2[comp[nod2]], Av = 0;
if (A2 > A2) swap(A1, A2);
query(1, 1, N);
int val = Av;
return max(val, queryARB(nod1, rT[what[L2[comp[nod2]]]]));
}
}
int main()
{
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
fin >> N >> M;
for (int i = 1; i <= N; ++i)
fin >> A[i];
for (int i = 1, nod1, nod2; i <= N - 1; ++i)
{
fin >> nod1 >> nod2;
V[nod1].push_back(nod2);
V[nod2].push_back(nod1);
}
niv[1] = 1;
preDfs(1);
memset(S, 0, sizeof(S));
Dfs(1);
setall(1, 1, N);
for (int i = 1, type; i <= M; ++i)
{
fin >> type;
if (type == 0)
{
int nod, val;
fin >> nod >> val;
A[nod] = val;
Ap = where[nod];
update(1, 1, N);
}
else
{
int nod1, nod2;
fin >> nod1 >> nod2;
fout << queryARB(nod1, nod2) << '\n';
}
}
fin.close();
fout.close();
}