Pagini recente » Cod sursa (job #556617) | Cod sursa (job #172281) | Cod sursa (job #771726) | Cod sursa (job #1343942) | Cod sursa (job #2728258)
#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];
pair<int, 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].first = adancime[liniarizare[i]];
rmq[i][0].second = liniarizare[i];
}
for (int l = 1; (1 << l) <= 2 * n - 1; l++)
{
for (int i = 1; i <= 2 * n - 1 - (1 << l) + 1; i++)
{
if (rmq[i][l - 1].first < rmq[i + (1 << (l - 1))][l - 1].first)
{
rmq[i][l].first = rmq[i][l - 1].first;
rmq[i][l].second = rmq[i][l - 1].second;
}
else
{
rmq[i][l].first = rmq[i + (1 << (l - 1))][l - 1].first;
rmq[i][l].second = rmq[i + (1 << (l - 1))][l - 1].second;
}
}
}
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);
}
if (rmq[primaAparitie[x]][putere2Max[primaAparitie[y] - primaAparitie[x] + 1]].first < rmq[primaAparitie[y] - (1 << putere2Max[primaAparitie[y] - primaAparitie[x] + 1]) + 1][putere2Max[primaAparitie[y] - primaAparitie[x] + 1]].first)
{
out << rmq[primaAparitie[x]][putere2Max[primaAparitie[y] - primaAparitie[x] + 1]].second << '\n';
}
else
{
out << rmq[primaAparitie[y] - (1 << putere2Max[primaAparitie[y] - primaAparitie[x] + 1]) + 1][putere2Max[primaAparitie[y] - primaAparitie[x] + 1]].second << '\n';
}
}
return 0;
}