Pagini recente » Cod sursa (job #1565588) | Cod sursa (job #793354) | Cod sursa (job #188659) | Cod sursa (job #2542694) | Cod sursa (job #1840225)
#include <bits/stdc++.h>
#define FIT(x, v) for (vector<int>::iterator x = v.begin(); x!=v.end(); ++x)
using namespace std;
const int MAX = 100001;
vector <int> graf[MAX];
vector <int> noduri_lant[MAX];
int sz, maxim;
int tata[MAX];
int numar_lanturi;
int poz[MAX];
int lg[MAX];
int dp[20][MAX];
int subarb[MAX];
int lant[MAX];
int nivel_lant[MAX];
void dfs (int nod)
{
subarb[nod] = 1;
int where = 0;
FIT (x, graf[nod])
{
dfs (*x);
subarb[nod] += subarb[*x];
if (subarb[where] < subarb[*x])
where = *x;
}
if (graf[nod].size() == 0)
{
++numar_lanturi;
lant[nod] = numar_lanturi;
noduri_lant[numar_lanturi].push_back(nod);
poz[nod] = 0;
return ;
}
lant[nod] = lant[where];
noduri_lant[lant[nod]].push_back(nod);
poz[nod] = noduri_lant[lant[nod]].size()-1;
}
void dfs2 (int nod)
{
if (poz[nod] == noduri_lant[lant[nod]].size() - 1)
{
++sz;
nivel_lant[lant[nod]] = sz;
maxim = max(maxim, sz);
}
dp[0][nod] = tata[noduri_lant[lant[nod]].back()];
FIT(x, graf[nod])
dfs2(*x);
if (poz[nod] == noduri_lant[lant[nod]].size() - 1)
--sz;
}
int LCA (int x, int y)
{
int lantx = lant[x], lanty = lant[y];
if (nivel_lant[lantx] < nivel_lant[lanty])
swap(x, y);
lantx = lant[x];
lanty = lant[y];
int diferenta = nivel_lant[lantx] - nivel_lant[lanty];
for (int put = lg[diferenta]+1; put >= 0; --put)
if (1<<put <= diferenta)
diferenta -= (1<<put), x = dp[put][x];
lantx = lant[x];
if (lantx == lanty)
{
if (poz[x]>poz[y])
return x;
return y;
}
for (int put = lg[nivel_lant[lantx]]+1; put>=0; --put)
{
if ((nivel_lant[lantx] > (1<<put)) && (lant[dp[put][x]] != lant[dp[put][y]]))
{
x = dp[put][x];
y = dp[put][y];
lantx = lant[x];
}
}
x = dp[0][x];
y = dp[0][y];
if (poz[x]>poz[y])
return x;
return y;
}
int main()
{
ifstream fin ("lca.in");
ofstream fout ("lca.out");
int n, m, x, y;
fin >> n >> m;
for (int i = 2; i<=n; ++i)
{
fin >> tata[i];
graf[tata[i]].push_back(i);
lg[i] = lg[i>>1] + 1;
}
dfs(1);
dfs2(1);
for (int i = 1; i <= lg[maxim]+1; ++i)
for (int j = 1; j<=n; ++j)
dp[i][j] = dp[i-1][dp[i-1][j]];
for (int i = 0; i<m; ++i)
{
fin >> x >> y;
fout << LCA (x, y) << '\n';
}
return 0;
}