Pagini recente » Cod sursa (job #889937) | Cod sursa (job #849353) | Cod sursa (job #1069004) | Cod sursa (job #2136142) | Cod sursa (job #3200005)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
#define limn 100010
int N, Q, k;
int dad[limn], depth[limn], poz[limn];
int rmq[20][limn], lg[limn];
// dad[i] = parintele lui i
// depth[i] = depth pt nodul i
vector<int> G[limn];
void euler(int node)
{
rmq[0][++k] = node;
poz[node] = k;
depth[node] = depth[dad[node]] + 1;
for (auto it : G[node])
{
euler(it);
rmq[0][++k] = node;
}
}
int main()
{
int x, y;
int pozX, pozY;
fin >> N >> Q;
for (int i = 2; i <= N; i++)
{
fin >> dad[i];
G[dad[i]].push_back(i);
}
dad[1] = 1;
depth[1] = 0; // depth in radacina e 0
// path eulerian = dfs din 1
euler(1);
for(int i = 1; i <= k; ++i)
cout << rmq[0][i] << ' ';
cout << endl;
// construim rmq
for (int i = 1; (1 << i) <= k; i++)
for (int j = 1; j + (1 << i) <=k+1; j++)
{
// calculam rmq[i][j]
if (depth[rmq[i - 1][j]] < depth[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))];
}
// raspundem la query-uri
while (Q--)
{
fin >> x >> y;
x = poz[x];
y = poz[y];
if (x > y)
swap(x, y);
int diff = y-x+1;
int lg = 0;
while(diff >>= 1)
lg++;
cout << x << ' ' << y << ' ' << lg << endl;
int level = lg;
if (depth[rmq[level][x]] < depth[rmq[level][y - (1 << level) + 1]])
fout << rmq[level][x] << '\n';
else
fout << rmq[level][y - (1 << level) + 1] << '\n';
}
return 0;
}