Pagini recente » Cod sursa (job #635173) | Borderou de evaluare (job #2005060) | Borderou de evaluare (job #2866269) | Borderou de evaluare (job #1133495) | Cod sursa (job #1969260)
#include<fstream>
#include<vector>
#define NMAX 100000
#define INF 2000000000
using namespace std;
vector<int> G[NMAX + 5];
int n, m, x, y, _length, p;
int lca_first[NMAX + 5];
int nn;
int _p[2 * NMAX + 5];
bool u[NMAX + 5];
struct _struct
{
int niv;
int nod;
};
_struct sol;
_struct d[18][2 * NMAX];
ifstream _cin("lca.in");
ofstream _cout("lca.out");
_struct min_defined(_struct x, _struct y)
{
if(x.niv == y.niv)
{
if(x.nod < y.nod)
{
return x;
}else
{
return y;
}
}else
{
if(x.niv < y.niv)
{
return x;
}else
{
return y;
}
}
}
void d_euler(int nod, int niv)
{
u[nod] = 1;
d[0][++nn].nod = nod;
d[0][nn].niv = niv;
lca_first[nod] = nn;
for(int i = 0; i < G[nod].size(); i++)
{
int fiu = G[nod][i];
if(u[fiu] == 0)
{
d_euler(fiu, niv + 1);
d[0][++nn].nod = nod;
d[0][nn].niv = niv;
}
}
}
void power_calculation()
{
for(int i = 1 + 1; i <= 2 * NMAX; i++)
{
_p[i] = 1 + _p[i / 2];
}
}
void rmq()
{
for(int i = 1; (1 << i) <= nn; i++)
{
for(int j = 1; j <= nn; j++)
{
d[i][j] = d[i - 1][j];
if(j + (1 << (i - 1)) <= nn)
{
d[i][j] = min_defined(d[i - 1][j],
d[i - 1][j + (1 << (i - 1))]);
}
}
}
}
int main()
{
_cin >> n >> m;
for(int i = 1 + 1; i <= n; i++)
{
_cin >> x;
G[x].push_back(i);
G[i].push_back(x);
}
d_euler(1, 1);
rmq();
power_calculation();
for(int i = 1; i <= m; i++)
{
sol.niv = INF;
_cin >> x >> y;
x = lca_first[x];
y = lca_first[y];
if(x > y)
{
swap(x, y);
}
_length = (y - x + 1);
p = _p[_length];
sol = min_defined(d[p][x],
d[p][y - (1 << p) + 1]);
_cout << sol.nod << "\n";
}
return 0;
}