Pagini recente » Cod sursa (job #1840617) | Cod sursa (job #1323183) | Cod sursa (job #3241456) | Cod sursa (job #492365) | Cod sursa (job #929591)
Cod sursa(job #929591)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector<int>g[100001];
int euler[4*100001], niv[100001*4], first[100001];
int rmq[4*100001][20], lg[100001*4];
int n, m, x, nr, y;
void Euler(int x, int lvl)
{
euler[++nr]=x;
niv[nr]=lvl;
first[x]=nr;
for(vector<int>::iterator it=g[x].begin(); it<g[x].end(); it++ )
{
Euler(*it,lvl+1);
euler[++nr]=x;
niv[nr]=lvl;
}
}
inline int Lca(int x, int y)
{
x = first[x], y = first[y];
if(x>y) swap(x,y);
int l = lg[y-x+1];
if(niv[rmq[x][l]] < niv[rmq[y-(1<<l)+1][l]])
return euler[rmq[x][l]];
return euler[rmq[y-(1<<l)+1][l]];
}
int main()
{
fin>>n>>m;
for(int i = 2; i<= n; i++ )
{
fin>>x;
g[x].push_back(i);
}
Euler(1,0);
for(int i = 1; i<= nr; i++ )
{
rmq[i][0]=i;
if(i>1) lg[i]=1+lg[i>>1];
}
for(int j = 1; (1<<j) <= nr; j++ )
for(int i = 1; i+(1<<j)-1 <= nr; i++ )
{
if(niv[rmq[i][j-1]] < niv[rmq[i+(1<<(j-1))][j-1]])
rmq[i][j]=rmq[i][j-1];
else rmq[i][j]=rmq[i+(1<<(j-1))][j-1];
}
for(int i = 1; i<= m; i++ )
{
fin >> x >> y;
fout << Lca(x,y) << '\n';
}
fin.close();
fout.close();
return 0;
}