Pagini recente » Cod sursa (job #1293124) | Cod sursa (job #3219104) | Cod sursa (job #1254147) | Cod sursa (job #15914) | Cod sursa (job #1619214)
#include <fstream>
#include <vector>
using namespace std;
ifstream is("lca.in");
ofstream os("lca.out");
using VI = vector<int>;
using VVI = vector<VI>;
int n, m, N;
VI e, nv, poz, log2;
VVI g, r;
void read();
void euler(int nod, int niv);
void rmq();
void query();
int main()
{
read();
e.push_back(0);
nv.push_back(0);
poz = VI(2 * n + 1);
euler(1, 1);
rmq();
query();
is.close();
os.close();
return 0;
}
void query()
{
int x, y, v;
while ( m-- )
{
is >> x >> y;
x = poz[x];
y = poz[y];
if ( x > y )
swap(x, y);
v = log2[y - x + 1];
if ( nv[r[x][v]] < nv[r[y - (1 << v) + 1][v]] )
os << e[r[x][v]] << "\n";
else
os << e[r[y - (1 << v) + 1][v]] << "\n";
}
}
void euler(int nod, int niv)
{
poz[nod] = e.size();
e.push_back(nod);
nv.push_back(niv);
for ( const auto &nodv : g[nod] )
if ( !poz[nodv] )
{
euler(nodv, niv + 1);
e.push_back(nod);
nv.push_back(niv);
}
}
void rmq()
{
N = 2 * n - 1;
log2 = VI(N + 1);
for ( int i = 2; i <= N; ++i )
log2[i] = log2[i / 2] + 1;
r = VVI(N + 1, VI(20));
for ( int i = 1; i <= N; ++i )
r[i][0] = i;
for ( int j = 1; ( 1 << j ) <= N; ++j )
for ( int i = 1; i + ( 1 << j ) - 1 <= N; ++i )
if ( nv[r[i][j - 1]] < nv[r[i + ( 1 << (j - 1) )][j - 1]] )
r[i][j] = r[i][j - 1];
else
r[i][j] = r[i + ( 1 << (j - 1) )][j - 1];
}
void read()
{
is >> n >> m;
g = VVI(n + 1);
int x;
for ( int i = 2; i <= n; ++i )
{
is >> x;
g[x].push_back(i);
}
}