Pagini recente » Cod sursa (job #3361489) | Cod sursa (job #3361944) | Cod sursa (job #3360349) | Cod sursa (job #3361406) | Cod sursa (job #3361283)
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int MAX_N = 100000,
MAX_LOG2 = 17;
vector<int> adj[MAX_N + 1];
int ancestor[MAX_LOG2 + 1][MAX_N + 1];
int tin[MAX_N + 1], tout[MAX_N + 1];
int parent[MAX_N + 1];
int n, q;
void Read()
{
f >> n >> q;
for(int v = 2; v <= n; v++)
{
int u;
f >> u;
parent[v] = u;
adj[u].push_back(v);
}
}
void Preprocess()
{
for(int i = 1; i <= n; i++)
ancestor[0][i] = parent[i];
for(int k = 1; k <= MAX_LOG2; k++)
for(int i = 1; i <= n; i++)
if(ancestor[k - 1][i])
ancestor[k][i] = ancestor[k - 1][ancestor[k - 1][i]];
}
int timer = 0;
void DFS(int node)
{
tin[node] = (++timer);
for(int child : adj[node])
DFS(child);
tout[node] = (++timer);
}
inline bool Ancestor(int x, int y)
{
return tin[x] <= tin[y] && tout[y] <= tout[x];
}
int LCA(int x, int y)
{
if(Ancestor(x, y))
return x;
if(Ancestor(y, x))
return y;
for(int k = MAX_LOG2; k >= 0; k--)
{
int z = ancestor[k][x];
if(z && !Ancestor(z, y))
x = z;
}
return ancestor[0][x];
}
void Solve()
{
while(q--)
{
int x, y;
f >> x >> y;
g << LCA(x, y) << '\n';
}
}
int main()
{
Read();
Preprocess();
DFS(1);
Solve();
f.close();
g.close();
return 0;
}