Pagini recente » Voteaza Zaharel | Clasamentul arhivei Infoarena Monthly | Istoria paginii runda/everest/clasament | Istoria paginii runda/vot/voteaza_miruna/clasament | Cod sursa (job #1984407)
#include <fstream>
#include <stdio.h>
#include <vector>
using namespace std;
ifstream is("lca.in");
ofstream os("lca.out");
//FILE* is = fopen("lca.in", "r");
//FILE* os = fopen("lca.out", "w");
int n, m, nr;
vector<vector<int> > G;
vector<int> euler, depth, first, K;
int M[500001][20];
void Read();
void Euler(int x, int d = 0);
void RMQ();
int Query(int a, int b);
int lca(int x, int y);
void Preprocesare();
int main()
{
Read();
euler.push_back(0);
Euler(1);
nr = euler.size()-1;
Preprocesare();
RMQ();
/*
for ( int i = 1; i <= nr; ++i )
os << euler[i] << " ";
os << "\n";
for ( int i = 1; i <= nr; ++i )
os << depth[euler[i]] << " ";
os << "\n";
for ( int i = 1; i <= nr; ++i )
{
for ( int j = 0; j <= nr; ++j )
os << M[i][j] << ' ';
os << '\n';
}
return 0;
*/
for ( int i = 0, x, y; i < m; ++i )
{
is >> x >> y;
//fscanf(is, "%d%d", &x, &y);
//fprintf(os, "%d\n", lca(x, y));
os << lca(x, y) << "\n";
}
//fclose(is);
//fclose(os);
is.close();
os.close();
return 0;
}
void Read()
{
is >> n >> m;
//fscanf(is, "%d%d", &n, &m);
G.resize(n+1);
first.resize(n+1);
depth.resize(n+1);
for ( int i = 2, x; i <= n; ++i )
{
is >> x;
//fscanf(is, "%d", &x);
G[x].push_back(i);
}
}
void Euler(int x, int d)
{
euler.push_back(x);
depth[x] = d;
first[x] = euler.size() - 1;
for ( auto it : G[x] )
{
Euler(it, d+1);
euler.push_back(x);
}
}
void Preprocesare()
{
K.resize(nr+1);
for ( int i = 2; i <= nr; ++i )
K[i] = 1 + K[i/2];
}
void RMQ()
{
for ( int i = 1; i <= nr; ++i )
M[i][0] = i;
for ( int j = 1; 1 << j <= nr; ++j )
for ( int i = 0; i + (1<<j) - 1 <= nr; ++i )
{
int p1 = M[i][j-1];
int p2 = M[i+ (1<< j-1 ) ][j-1];
if ( depth[euler[p1]] < depth[euler[p2]] )
M[i][j] = p1;
else
M[i][j] = p2;
}
}
int lca(int x, int y)
{
x = first[x];
y = first[y];
if ( x > y )
{
int aux = x;
x = y;
y = aux;
}
int p = Query(x, y);
return euler[p];
}
int Query(int i, int j)
{
int k = K[j-i+1];
int p1 = M[i][k];
int p2 = M[j - (1<<k) + 1 ][k];
if ( depth[euler[p1]] < depth[euler[p2]] )
return p1;
return p2;
}