Pagini recente » Borderou de evaluare (job #2486108) | Borderou de evaluare (job #865365) | Borderou de evaluare (job #1947748) | Borderou de evaluare (job #1561059) | Cod sursa (job #1537905)
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
#define nmax 100005
ifstream f("lca.in");
ofstream g("lca.out");
int euler[2*nmax],
lev[nmax],
first[nmax],
log[2*nmax],
rmq[18][2*nmax],
nod[18][2*nmax];
vector<int> v[nmax];
int n,m,cnt = 0;
void DFS(int x)
{
euler[++cnt] = x;
first[x] = cnt;
for(int i = 0; i < v[x].size(); i++)
{
int nod = v[x][i];
lev[nod] = lev[x] + 1;
DFS(nod);
euler[++cnt] = x;
}
}
int lca(int x, int y)
{
x = first[x];
y = first[y];
if (x > y)
swap(x,y);
int dif = y - x + 1;
int p = log[dif];
if (rmq[p][x] < rmq[p][y - (1<<p) + 1])
return nod[p][x];
return nod[p][y - (1<<p) + 1];
}
void RMQ()
{
for(int i = 1; i<=cnt; i++)
{
rmq[0][i] = lev[euler[i]];
nod[0][i] = euler[i];
}
for(int i = 1; (1<<i) <= cnt; i++)
for(int j = 1; j + (1<<i) - 1 <= cnt; j++)
if (rmq[i-1][j] < rmq[i-1][j+ (1<<(i-1))])
{
rmq[i][j] = rmq[i-1][j];
nod[i][j] = nod[i-1][j];
}
else
{
rmq[i][j] = rmq[i-1][j + (1<<i-1)];
nod[i][j] = nod[i-1][j + (1<<i-1)];
}
}
int main()
{
f >> n >> m;
for(int i = 1; i <= n - 1; i++)
{
int tata;
f >> tata;
v[tata].push_back(i+1);
}
DFS(1);
for(int i = 2; i<=cnt ; i++)
log[i] = log[i/2] + 1;
RMQ();
int x,y;
for(int i = 1; i<=m; i++)
{
f >> x >> y;
g << lca(x,y) << '\n';
}
return 0;
}