Pagini recente » Cod sursa (job #2030945) | Cod sursa (job #1887938) | Istoria paginii runda/asdasdassdasd/clasament | Cod sursa (job #395944) | Cod sursa (job #2196976)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int N=100005;
int n,rmq[21][2*N],q,timp,e[2*N],nr,nivel[N],upoz[N],log[2*N];
bool viz[N];
vector <int> a[N];
void citire()
{
in>>n>>q;
for(int i=2; i<=n; i++)
{
int x;
in>>x;
a[x].push_back(i);
}
}
void precalculare()
{
int i;
log[1]=0;
for(i=2; i<=2*n; i++)
log[i]=log[i/2]+1;
}
void dfs(int nod)
{
int i,vecin;
e[++nr] = nod;
viz[nod]=1;
for(i=0; i<a[nod].size(); i++)
{
vecin=a[nod][i];
if(!viz[vecin])
{
nivel[vecin]=nivel[nod]+1;
dfs(vecin);
e[++nr] = nod;
}
}
}
void RMQ()
{
int i,j;
for(i=1; i<=2*n; i++)
rmq[0][i]=e[i];
for(i=1; 1<<i <= n ; i ++)
for(j=(1<<i); j<=2*n; j++)
{
if (nivel[rmq[i-1][j]] < nivel[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))];
}
}
}
void lca(int x,int y)
{
x = upoz[x];
y = upoz[y];
if(x>y)
swap(x,y);
int l=log[y-x+1];
if(nivel[rmq[l][y]] < nivel[rmq[l][x+(1<<l)-1]])
{
out<<rmq[l][y]<<'\n';
//out<<l<<" "<<y<<endl;
}
else
{
out<<rmq[l][x+(1<<l)-1]<<'\n';
//out<<l<<" "<<x+(1<<l)-1<<endl;
}
}
void raspuns()
{
while(q--)
{
int x,y;
in>>x>>y;
lca(x,y);
}
}
int main()
{
int i,j;
citire();
precalculare();
dfs(1);
/*
for(i=1; i<=n; i++)
out<<log[i]<<" ";
out<<endl;
for(i=1; i<=nr; i++)
out<<e[i]<<" ";
out<<endl;
*/
for(i=1; i<=nr; i++)
{
upoz[e[i]]=i;
}
/*for(i=1; i<=n; i++)
out<<upoz[i]<<" ";
out<<endl;
for(i=1; i<=n; i++)
out<<nivel[i]<<" ";
out<<endl;
*/
RMQ();
/* for(i=0; 1<<i <=n ; i++)
{
for(j=1; j<=2*n; j++)
out<<rmq[i][j]<<" ";
out<<endl;
}
*/
raspuns();
return 0;
}