Pagini recente » Cod sursa (job #1086839) | Cod sursa (job #2977475) | Cod sursa (job #1390516) | Cod sursa (job #1525674) | Cod sursa (job #2857616)
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#define MAX (1<<30)-1
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n,m,cnt;
int euleriana[200004],niveluri[200004],poz_noduri[100001];
int rmq_dp[200005][30];
vector<int>adiacenta[100001];
void citire()
{
f >> n >> m;
for(int i = 2;i<=n;i++)
{
int tata;
f >> tata;
adiacenta[tata].push_back(i);
}
}
// facem o parcurgere euleriana
// si salvam nivelul pe care se afla nodurile si pozitia nodurilor in parvurgerea euleriana
void parcurgere_euleriana(int nod,int nivel)
{
euleriana[++cnt] = nod;
niveluri[cnt] = nivel;
poz_noduri[nod] = cnt;
for(auto x:adiacenta[nod])
{
parcurgere_euleriana(x,nivel+1);
euleriana[++cnt] = nod;
niveluri[cnt] = nivel;
}
}
//apoi facem rmq dintre pozitiile a doua noduri date intr-un query avand ca rezultat nivelul minim care se afla intre acestea
void init_rmq()
{
for(int i = 1;i<=cnt;i++)
{
rmq_dp[i][0] = i;
}
}
void rmq()
{
int lungime;
lungime = log2(cnt)+1;
for(int j = 1;j<=lungime;j++)
{
for(int inceput = 1;inceput+(1<<(j-1))-1<=cnt;inceput++)
{
if(niveluri[rmq_dp[inceput][(j-1)]]<niveluri[rmq_dp[inceput+(1<<(j-1))][(j-1)]])
{
rmq_dp[inceput][j] = rmq_dp[inceput][(j-1)];
}
else
{
rmq_dp[inceput][j] = rmq_dp[inceput+(1<<(j-1))][(j-1)];
}
}
}
}
int aflare_rasp(int x,int y)
{
int lungime = log2(y-x+1);
int poz_min;
if(niveluri[rmq_dp[x][lungime]]>niveluri[rmq_dp[y-(1<<lungime)+1][lungime]])
return euleriana[rmq_dp[y-(1<<lungime)+1][lungime]];
return euleriana[rmq_dp[x][lungime]];
}
void querys()
{
for(int i = 1;i<=m;i++)
{
int x,y;
f >> x >> y;
// gasim pozitia lui x si y in vectorul cu desfasurarea si gasim rezultatul cu ajutorul rmq
int pozx = poz_noduri[x],pozy = poz_noduri[y];
if(pozx>pozy)swap(pozx,pozy);
g << aflare_rasp(pozx,pozy)<< '\n';
}
}
int main()
{
citire();
parcurgere_euleriana(1,0);
init_rmq();
rmq();
querys();
}