Pagini recente » Cod sursa (job #1937368) | Cod sursa (job #1747437) | Cod sursa (job #556887) | Cod sursa (job #2426318) | Cod sursa (job #2213288)
#include <iostream>
#include <fstream>
#include <vector>
#define infinit 999999999
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int tati[100010], parcurgere[400010], nivel[400010], prima[100010], viz[100010];
int dp[400010][22] = {infinit}, log[400010];
int k = 1;
int parcurgere_euleriana(int nod, int nivel_actual, int n)
{
parcurgere[k] = nod;
nivel[k] = nivel_actual;
if(viz[nod] == 0)
{
prima[nod] = k;
viz[nod] = 1;
}
k++;
for(int i = 1; i <= n; i++)
{
if(tati[i] == nod)
{
parcurgere_euleriana(i, nivel_actual + 1, n);
parcurgere[k] = nod;
nivel[k] = nivel_actual;
k++;
}
}
return 0;
}
int minim(int a, int b)
{
if(a == infinit)
return b;
if(b == infinit)
return a;
if(nivel[a] < nivel[b])
return a;
return b;
}
int minim_corect(int a, int b, int x, int y)
{
// cout <<a <<" "<< x << endl;
// cout << b << " " << y << endl;
if(a < b)
return x;
return y;
}
int t = 0;
int interogare(int x, int y)
{
t++;
if(x == y)
return x;
else
{
int dif;
dif = y - x ;
return minim(dp[x][log[dif]], dp[y-(1<<log[dif])][log[dif]]);
}
}
int main()
{
int n, m, x, i, j, y;
f >> n >> m;
tati[1] = 0;
for(int i = 2; i <= n ; i++)
{
f >> tati[i];
}
parcurgere_euleriana(1, 0, n);
/* for(int i = 0; i < k; i++)
g << parcurgere[i] << " ";
g << '\n';
for(int i = 0; i < k; i++)
g << nivel[i] << " ";
*/
for(i = 1; i <= k; i++)
dp[i][0] = minim_corect(nivel[i], nivel[i+1], i, i+1);
dp[k][0] = parcurgere[k];
for(i = 2; i <= k; i++)
{
log[i] = log[i/2] + 1;
}
for(int j = 1; j <= log[k]; j++)
{
for(int i = 1;(i + (1 << (j-1))) <= k ; i++)
{
// cout << "CRAPAAAA" << " " << i << endl;
// cout << dp[i][j-1] << " " << dp[i + (1 << (j-1))][j-1] << endl;
dp[i][j] = minim(dp[i][j-1], dp[i + (1 << (j-1))][j-1]);
}
}
// cout << "AJUNGE AICI?" <<endl;
/* for(int i = 1; i <= k; i++)
cout << i <<" " << parcurgere[i] << " " << nivel[i] << endl; */
// cout << endl;
for(int i = 0; i < m; i++)
{
f >> x >> y;
//cout << prima[x] << " " << prima[y] << " " << endl;
if(prima[x] < prima[y])
g << parcurgere[interogare(prima[x], prima[y])] << '\n';
else
g << parcurgere[interogare(prima[y], prima[x])] << '\n';
//cout << endl << endl;
}
return 0;
}