Pagini recente » Cod sursa (job #152544) | Cod sursa (job #2019483) | Cod sursa (job #1843503) | Cod sursa (job #1805246) | Cod sursa (job #2368431)
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#define NMAX 100001
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
//int M[2 * NMAX][22];
vector <int> v[NMAX], e, niv, poz;
vector < vector<int> > M;
void DF(int nod, int nivel)
{
int vec, sz = v[nod].size(), i;
e.push_back(nod); //euler
niv.push_back(nivel); //nivel
if(!poz[nod]) //prima pozitie a nodului in sirul euler
poz[nod] = e.size() - 1;
for(i=0; i<sz; ++i)
if(!poz[v[nod][i]]){
DF(v[nod][i], nivel + 1);
e.push_back(nod);
niv.push_back(nivel);
}
}
int query(int x, int y)
{
int k = log2(y - x + 1);
if(niv[ M[x][k] ] < niv[ M[y - (1<<k) + 1][k] ])
return e[ M[x][k] ];
else return e[ M[y - (1<<k) + 1][k] ];
}
int main()
{
int n, m, nod, vec, i, j;
e.push_back(0);
niv.push_back(0);
f >> n >> m;
poz = vector<int>(n + 1, 0);
M = vector< vector<int> > (2 * n + 1, vector<int>(22, 0));
for(nod=2; nod<=n; ++nod){ //Citire
f>>vec;
v[nod].push_back(vec);
v[vec].push_back(nod);
}
DF(1, 0); //Drum euler
for(i=1; i <= e.size(); ++i) //RMQ init
M[i][0] = i;
for(j=1; (1<<j) <= e.size(); ++j)
for(i=1; i <= e.size() - (1<<j) + 1; ++i)
if(niv[ M[i][j - 1] ] < niv[ M[i + (1<<(j - 1))][j - 1] ])
M[i][j] = M[i][j - 1];
else
M[i][j] = M[i + (1<<(j - 1))][j - 1];
for(i=1; i<=m; ++i){ //Query
f >> nod >> vec;
nod = poz[nod];
vec = poz[vec];
if(nod > vec)
swap(nod, vec);
g << query(nod, vec) << '\n';
}
return 0;
}