Pagini recente » Cod sursa (job #3001876) | Cod sursa (job #375799) | Cod sursa (job #1097895) | Cod sursa (job #2334721) | Cod sursa (job #1585511)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int N=100001;
vector<int>H[N];
int apar[N],lev[100*N],nr[100*N],dp[25][100*N],lg[100*N];
int k;
void dfs(int x,int lvl)
{
lev[++k]=lvl;//lev=>nivelul de pe pozitia k in repr euler;
nr[k]=x;//nr=>nodul de pe pozitia k in reprz euler;
apar[x]=k;//apar=>prima aparitie a nodului X in reprz euler;
for(vector<int>::iterator it=H[x].begin();it!=H[x].end();it++)
{
dfs(*it,lvl+1);
nr[++k]=x;
lev[k]=lvl;
}
}
void rmq()
{
int i,j;
for(i=2;i<=k;i++) lg[i]=lg[i>>1]+1;
for(i=1;i<=k;i++) dp[0][i]=i;
for(i=1;(1<<i)<k;i++)
{
for(j=1;j<=k-(1<<i);j++)
{
dp[i][j]=dp[i-1][j];
if(lev[dp[i-1][j]]>lev[dp[i-1][j+(1<<(i-1))]]) dp[i][j]=dp[i-1][j+(1<<(i-1))];
};
}
}
int lca(int x, int y)
{
//LCA-ul nodurilor x si y va fi nodul cu nivel minim din secventa (First[x], First[y]) din reprezentarea Euler a arborelui
int diff, l, sol, sh;
int a = apar[x], b = apar[y];
if(a > b) swap(a, b);
diff = b - a + 1;
l = lg[diff];
sol = dp[l][a];
sh = diff - (1 << l);
if(lev[sol] > lev[dp[l][a + sh]])
sol = dp[l][a + sh];
return nr[sol];
}
int main()
{
int n,m,i,a,b;
fin>>n>>m;
for(i=2;i<=n;i++)
{
fin>>a;
H[a].push_back(i);
}
dfs(1,0);
rmq();
for(i=1;i<=m;i++)
{
fin>>a>>b;
fout<<lca(a,b)<<"\n";
}
}