Pagini recente » Cod sursa (job #420942) | Cod sursa (job #2738671) | Cod sursa (job #2553751) | Cod sursa (job #1757809) | Cod sursa (job #2728253)
#include <fstream>
#include <vector>
using namespace std;
/// complexitate 1 per query cu RMQ (solutie finala)
const int NMAX = 100000;
const int LOG = 18;
vector<int> graf[1 + NMAX];
int rmq[1 + 2 * NMAX - 1][LOG]; /// 2 * NMAX - 1 celule e suficient
vector<int> liniarizare;
int adancime[1 + NMAX];
int primaAparitie[1 + NMAX];
int putere2Max[1 + 2 * NMAX - 1]; /// 2 * NMAX - 1 celule e suficient
int n;
void dfs(int nod, int adanc)
{
liniarizare.emplace_back(nod);
primaAparitie[nod] = liniarizare.size() - 1;
adancime[nod] = adanc;
for (int i = 0; i < graf[nod].size(); i++)
{
dfs(graf[nod][i], 1 + adanc);
liniarizare.emplace_back(nod);
}
}
void RMQ()
{
for (int i = 1; i <= 2 * n - 1; i++)
{
rmq[i][0] = adancime[liniarizare[i]];
}
for (int l = 1; (1 << l) <= 2 * n - 1; l++)
{
for (int i = 1; i <= 2 * n - 1 - (1 << l) + 1; i++)
{
rmq[i][l] = min(rmq[i][l - 1], rmq[i + (1 << (l - 1))][l - 1]);
}
}
int putere2 = 1;
int exp = 0;
for (int i = 1; i <= 2 * n - 1; i++)
{
if (putere2 * 2 <= i)
{
putere2 *= 2;
exp++;
}
putere2Max[i] = exp;
}
}
int main()
{
ifstream in("lca.in");
ofstream out("lca.out");
int m;
in >> n >> m;
for (int i = 2; i <= n; i++)
{
int x;
in >> x;
graf[x].emplace_back(i);
}
liniarizare.emplace_back(0);
dfs(1, 1);
RMQ();
for (int j = 1; j <= m; j++)
{
int x, y;
in >> x >> y;
if (primaAparitie[x] > primaAparitie[y])
{
swap(x, y);
}
out << min(rmq[primaAparitie[x]][putere2Max[primaAparitie[y] - primaAparitie[x] + 1]], rmq[primaAparitie[y] - (1 << putere2Max[primaAparitie[y] - primaAparitie[x] + 1]) + 1][putere2Max[primaAparitie[y] - primaAparitie[x] + 1]]) << '\n';
}
return 0;
}