Pagini recente » Cod sursa (job #376658) | Cod sursa (job #1488061) | Cod sursa (job #1299233) | Cod sursa (job #1269052) | Cod sursa (job #2989153)
#include <fstream>
#include <vector>
#include <cmath>
#define NMAX 100005
#define MMAX 2000005
#define LOG_MAX 17
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int father[NMAX];
int table[NMAX][LOG_MAX + 1];
int lvl[NMAX];
vector <int> adj[NMAX];
void dfs(int node)
{
for (int i = 0; i < adj[node].size(); ++i)
{
int vecin = adj[node][i];
lvl[vecin] = lvl[node] + 1;
dfs(vecin);
}
}
int lca(int a, int b)
{
if (lvl[a] > lvl[b])
swap(a, b);
if (lvl[a] < lvl[b])
{
int log = log2(lvl[b] - lvl[a]);
while (log >= 0 && lvl[b] > lvl[a])
{
if (lvl[b] - (1 << log) >= lvl[a])
b = table[b][log];
--log;
}
}
if (a != b)
{
for (int i = LOG_MAX - 1; i >= 0; --i)
{
if (table[a][i] != 0 && table[a][i] != table[b][i])
{
a = table[a][i];
b = table[b][i];
}
}
a = table[a][0];
b = table[b][0];
}
return a;
}
int main()
{
int n, m, i, j, a, b, p;
in >> n >> m;
for (i = 2; i <= n; ++i)
{
in >> father[i];
adj[father[i]].push_back(i);
table[i][0] = father[i];
}
lvl[1] = 0;
dfs(1);
for (p = 1; p < LOG_MAX; ++p)
{
for (i = 1; i <= n; ++i)
table[i][p] = table[table[i][p - 1]][p - 1];
}
for (i = 1; i <= m; ++i)
{
in >> a >> b;
out << lca(a, b) << '\n';
}
return 0;
}