Pagini recente » Cod sursa (job #2941851) | Cod sursa (job #3310675) | Cod sursa (job #3325731) | Cod sursa (job #3312715) | Cod sursa (job #3326988)
#include <fstream>
#include <vector>
#define NMAX 100002
#define DIM 210000
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
int n;
vector<vector<int>> graf;
int rmq[DIM][26], m; //m = nr querryuri
//pt LCA:
int Euler[DIM], nivel[DIM], first[NMAX];
int indic = 0; //nr de elemente din Euler
void citire();
void calcRMQ();
void DFS(int nod, int depth);
int main()
{
citire();
DFS(1, 0);
calcRMQ();
return 0;
}
void calcRMQ()
{
int i, exp, power, u, v, l, r, lgsecv;
//citire si precalculare pt lungime 1
for(i = 1; i <= indic; i++) rmq[i][0] = i;
//rmq
for(power = 2, exp = 1; power <= indic; power *= 2, exp++) //power = puterea efectiva; j = exponentul pentru care se atinge puterea
for(i = 1; i + power - 1 <= indic; i++)
{
u = rmq[i][exp - 1];
v = rmq[i + power / 2][exp - 1];
if (nivel[u] < nivel[v])
rmq[i][exp] = u;
else
rmq[i][exp] = v;
}
//querry-urile
for(i = 1; i <= m; i++)
{
fin>>u>>v;
l = first[u];
r = first[v];
if(l > r) swap(l, r);
lgsecv = r - l + 1;
//calculeaza putere maxima care incape
power = 1;
exp = 0;
while(power <= lgsecv)
{
power *= 2;
exp++;
}
power /= 2;
exp--;
u = rmq[l][exp];
v = rmq[r - power + 1][exp];
if(nivel[u] < nivel[v])
fout<<Euler[u]<<'\n';
else
fout<<Euler[v]<<'\n';
}
}
void citire()
{
int i, x;
fin>>n>>m;
graf.resize(n + 2);
for(i = 2; i <= n; i++)
{
fin>>x;
graf[x].push_back(i);
}
}
void DFS(int nod, int depth)
{
nivel[++indic]= depth;
first[nod] = indic;
Euler[indic] = nod;
for(int i = 0; i < graf[nod].size(); i++)
{
DFS(graf[nod][i], depth + 1);
nivel[++indic]= depth;
Euler[indic] = nod;
}
}