Pagini recente » Cod sursa (job #712549) | Cod sursa (job #2715079) | Cod sursa (job #1623269) | Cod sursa (job #402836) | Cod sursa (job #2462540)
#include <fstream>
#include <vector>
#define pb push_back
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
void euler(int x);
void createRMQ();
int queryRMQ(int x, int y);
int LCA(int x, int y);
int n, m, nivel, poz, prima[100005], uz[100005], niv[200005], nod[200005], RMQ[20][200005];
vector<int> L[100005];
int main()
{
int i, x, y;
fin >> n >> m;
for (i = 2; i <= n; i++)
{
fin >> x;
L[x].pb(i);
L[i].pb(x);
}
euler(1);
createRMQ();
for (i = 1; i <= m; i++)
{
fin >> x >> y;
fout << LCA(x, y) << '\n';
}
return 0;
}
void euler(int x)
{
int i;
uz[x] = 1;
prima[x] = poz + 1;
for (i = 0; i < L[x].size(); i++)
if (!uz[L[x][i]])
{
uz[L[x][i]] = 1;
nod[++poz] = x;
niv[poz] = nivel;
nivel++;
euler(L[x][i]);
nivel--;
}
nod[++poz] = x;
niv[poz] = nivel;
}
void createRMQ()
{
int i, j, k, p2;
for (i = 1; i <= poz; i++)
RMQ[0][i] = i;
p2 = 1;
k = 0;
while ((p2 << 1) < poz)
{
p2 <<= 1;
k++;
}
for (j = 1, p2 = 2; j <= k; j++, p2 <<= 1)
for (i = 1; i + p2 - 1 <= poz; i++)
{
if (niv[RMQ[j - 1][i]] < niv[RMQ[j - 1][i + (p2 >> 1)]])
RMQ[j][i] = RMQ[j - 1][i];
else RMQ[j][i] = RMQ[j - 1][i + (p2 >> 1)];
}
}
int queryRMQ(int x, int y)
{
int p2 = 1, k=0;
while (x + (p2<<1) <= y)
{
p2 <<= 1;
k++;
}
if (niv[RMQ[k][x]] < niv[RMQ[k][y-p2+1]])
return RMQ[k][x];
return RMQ[k][y-p2+1];
}
int LCA(int x, int y)
{
x = prima[x];
y = prima[y];
if (x > y)
swap(x, y);
int aux = queryRMQ(x, y);
return nod[aux];
}