Pagini recente » Cod sursa (job #2112804) | Cod sursa (job #1710598) | Cod sursa (job #2775589) | Cod sursa (job #1245272) | Cod sursa (job #1355971)
#include <fstream>
#include <vector>
using namespace std;
ifstream is("lca.in");
ofstream os("lca.out");
void DF( int x, int niv );
int LCA(int x, int y);
void RMQ();
const int SIZE = 100001;
vector<int> v[SIZE];
int n, m;
int cnt;
int E[2*SIZE], niv[2*SIZE], poz[SIZE], log[2*SIZE];
int rmq[2*SIZE][19];
int main()
{
int x, y;
is >> n >> m;
for ( int i = 2; i <= n; ++i )
{
is >> x;
v[x].push_back(i);
}
DF(1, 1);
RMQ();
for ( int i = 2; i <= cnt; ++i )
log[i] = log[i/2] + 1;
for ( int i = 1; i <= m; ++i )
{
is >> x >> y;
os << LCA(x, y) << '\n';
}
is.close();
os.close();
return 0;
}
void DF(int x, int nv)
{
cnt++;
E[cnt] = x, niv[cnt] = nv, poz[x] = cnt;
for ( int i = 0; i < v[x].size(); ++i )
{
DF(v[x][i], nv+1);
cnt++;
E[cnt] = x, niv[cnt] = nv;
}
}
int LCA(int x, int y)
{
int k;
int st, dr;
st = poz[x];
dr = poz[y];
if ( st > dr )
swap(st, dr);
k = log[dr-st + 1];
if ( niv[rmq[st][k]] > niv[rmq[dr - (1 << k) + 1][k]] )
return E[rmq[dr - (1 << k) + 1][k]];
return E[rmq[st][k]];
}
void RMQ()
{
for ( int i = 1; i <= cnt; ++i )
rmq[i][0] = i;
for ( int j = 1; (1 << j) <= cnt; ++j )
for ( int i = 1; i + (1 << j) - 1 <= cnt; ++i )
{
if ( niv[rmq[i][j-1]] < niv[rmq[i + (1 << (j-1))][j-1]] )
rmq[i][j] = rmq[i][j-1];
else
rmq[i][j] = rmq[i + (1 << (j-1))][j-1];
}
}