Pagini recente » Cod sursa (job #1259092) | Cod sursa (job #898331) | Cod sursa (job #2539866) | Istoria paginii utilizator/frongeorgecosmin | Cod sursa (job #2085111)
#define DM 100001
#define DN 4000001
#include <fstream>
#include <vector>
using namespace std;
ifstream fi ("lca.in");
ofstream fo ("lca.out");
int n, m, a, b, rmq[21][DN], nvl[DM], lg[DN], ps[DM];
vector <int> v[DM], elr;//v - muchii; elr - reprezentare euler
void dfs(int nod, int p)
{
nvl[nod] = nvl[p] + 1;
elr.push_back(nod);
for (auto i:v[nod])
if (i != p)
dfs(i, nod);
elr.push_back(p);
}
int main()
{
fi >> n >> m;
for (int i = 2; i <= n; ++i)
{
fi >> a;
v[a].push_back(i);
v[i].push_back(a);
}
//parcurgere euler
nvl[1] = -1;
dfs(1, 1);
elr.pop_back();
//alcatuire rmq
for (int i = 2; i <= elr.size(); ++i)
lg[i] = lg[i/2] + 1;
for (int i = 0; i < elr.size(); ++i)
{
rmq[0][i+1] = elr[i];
if (!ps[elr[i]])
ps[elr[i]] = i + 1;
}
for (int i = 1; (1<<i) - 1 <= elr.size(); ++i)
for (int j = 1; j + (1<<i) - 1 <= elr.size(); ++j)
if (nvl[rmq[i-1][j]] < nvl[rmq[i-1][j+(1<<(i-1))]])
rmq[i][j] = rmq[i-1][j];
else
rmq[i][j] = rmq[i-1][j+(1<<(i-1))];
//rezolvare querry-uri
for (int i = 1; i <= m; ++i)
{
fi >> a >> b;
a = ps[a];
b = ps[b];
if (a > b)
swap(a, b);
if (nvl[rmq[lg[b-a]][a]] < nvl[rmq[lg[b-a]][b-(1<<lg[b-a])+1]])
fo << rmq[lg[b-a]][a] << '\n';
else
fo << rmq[lg[b-a]][b-(1<<lg[b-a])+1] << '\n';
}
return 0;
}