Pagini recente » Cod sursa (job #1888997) | Cod sursa (job #84566) | Cod sursa (job #2984989) | Cod sursa (job #1873845) | Cod sursa (job #969545)
Cod sursa(job #969545)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int n, m, K;
vector <int> G[100010];
int euler[200010], height[200010], first[100010];
int lg[200010], rmq[18][200010];
inline void DFS(int nod, int nivel)
{
K++;
euler[K] = nod; /// bagam nod in reprezentarea euler a grafului
height[K] = nivel; /// punem si nivelul la care se afla nod in graf
first[nod] = K; /// punem prima aparitie a nodului nod in reprezentarea euler
for (vector <int>::iterator it = G[nod].begin(); it!=G[nod].end(); it++)
{
DFS(*it, nivel+1);
K++;
euler[K] = nod; /// continuam reprezentarea euler a grafului
height[K] = nivel; /// si nivelul
}
}
inline void LG2()
{
/// lg[i] = partea intreaga a lui log in baza 2 de i;
int i;
for (i=2; i<=K; i++)
{
lg[i] = lg[i>>1] + 1;
}
}
inline void RMQ()
{
///rmq[i][j] = pozitia nodului de nivel minim din reprezentarea euler a grafului
/// dintr-un interval care incepe la pozitia j si are lungime 2^i
int i, j, lim;
for (i=1; i<=K; i++)
rmq[0][i] = i;
for (i=1; (1<<i) <= K; i++)
{
lim = K - (1<<i) + 1;
for (j=1; j <= lim; j++)
{
rmq[i][j] = rmq[i-1][j];
if (height[rmq[i][j]] > height[rmq[i-1][j+(1 << (i-1))]])
rmq[i][j] = rmq[i-1][j + (1 << (i-1))];
}
}
}
inline void compute()
{
DFS(1, 0);
LG2();
RMQ();
}
inline int lca (int x, int y)
{
int poz, dif, l;
x = first[x]; /// extrag pozitiile din reprezentarea euler unde se afla nodurile
y = first[y];
if (x > y)
swap(x, y);
dif = y - x + 1;
l = lg[dif];
poz = rmq[l][x];
if (height[poz] > height[rmq[l][x + dif - (1<<l)]])
poz = rmq[l][x + dif - (1<<l)];
return euler[poz];
}
int main()
{
ifstream f ("lca.in");
ofstream g ("lca.out");
f>>n>>m;
int i, x, y;
for (i=1; i<n; i++)
{
f>>x;
G[x].push_back(i+1);
}
compute();
while (m--)
{
f>>x>>y;
g<<lca(x, y)<<"\n";
}
f.close();
g.close();
return 0;
}