Pagini recente » Cod sursa (job #1908999) | Cod sursa (job #523494) | Cod sursa (job #2756236) | Cod sursa (job #342705) | Cod sursa (job #760763)
Cod sursa(job #760763)
#include<fstream>
#include<algorithm>
#include<vector>
#define nmax 100007
#define mmax 2000006
#define foreach(V) for(vector<int>::iterator it =V.begin() ; it != V.end(); it++)
#define fort(st,dr,i) for (int i = st; i <= dr; ++i )
#define MIN(a,b) (a>b ? b : a)
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector <int> v[nmax];
int N, L[nmax<<1], niv[nmax<<1] , K, pred[nmax<<1];//niv-nivelul , L-parcurgerea euler
int lg[nmax<<1], rmq[20][nmax<<1]; //rmq[i][j] - retine minimul din intervalul [j, j + i^2 -1], vectorul niv
int M;
void dfs(int nod, int nivel)
{
L[++K] = nod;//nodul actual este adaugat in rpeprezentarea euler
niv[K] = nivel;//niveulul fiecarei pozitii din reprezentarea euler a arborelui
pred[nod] = K;//pozitia pe care apare prima ddata fiecare nod
foreach(v[nod])
{
dfs(*it, nivel + 1);
L[++K] = nod;
niv[K] = nivel;
}
}
void read()
{
int x;
fin >>N>> M;
fort(2,N,i)
{
fin >> x;
v[x].push_back(i);
}
}
void LCA(int x, int y)
{
//lca(x,y)- nivelul minim din reprezentarea euler a arborelui
int a, b;
a = pred[x];
b = pred[y];
if(a>b)
swap(a,b);
int dif, sh, lgg,sol;
dif = b - a + 1;
lgg = lg[dif];
sh = dif - (1<<lgg);
sol= rmq[lgg][a];
if(niv[sol] > niv[rmq[lgg][a + sh]])
sol = rmq[lgg][a + sh];
fout << L[sol]<<'\n';
}
void Range_minimum_query()
{
fort(2,K,i)
lg[i] = lg[i/2] + 1;
fort(1,K,i)
rmq[0][i] = i;
for(int i = 1; (1<<i) <= K; i++)
{
int l = 1 <<(i - 1 );
int l2 = (1<<i);
for(int j = 1; j <= K - l2 + 1 ; j++)
{
rmq[i][j] = rmq[i-1][j];
if(niv[rmq[i][j]] > niv[rmq[i-1][j + l]])
rmq[i][j] = rmq[i - 1][j + l];
}
}
}
int main()
{
int x, y;
read();
dfs(1,0);
Range_minimum_query();
//fout<<"X";
fort(1, M, i)
fin>>x >>y , LCA(x,y);
fin.close();
return 0;
}