Pagini recente » Cod sursa (job #2587908) | Cod sursa (job #882031) | Cod sursa (job #1966601) | Rating Bogdan Ionelia Daniela (ionelia) | Cod sursa (job #1397336)
#include <cstdio>
#include <vector>
#define NMAX 100010
using namespace std;
FILE*fin=fopen ("lca.in", "r");
FILE*fout=fopen ("lca.out", "w");
int n, m;
int A[4*NMAX], lga, log2lga;
int Euler[4*NMAX];
int M[4*NMAX][20];
int first[NMAX];
vector <int> L[NMAX];
void citire();
void DFS (int, int);
void precalculare();
int query(int, int);
void rez();
void afisare();
int main()
{
int i, x;
//citesc fii
fscanf(fin, "%d %d", &n, &m);
for (i=1; i<n; ++i)
{
fscanf(fin, "%d", &x);
L[x].push_back(i+1);
}
DFS(1, 0);
precalculare();
rez();
return 0;
}
void DFS (int nod, int nvl)
{
int i;
A[++lga]=nvl;//parcurgere euler, doar ca retin nivelurile in loc de noduri
Euler[lga]=nod;
if (!first[nod])
first[nod]=lga;
for (i=0; i<L[nod].size(); ++i)
{
DFS (L[nod][i], nvl+1);
A[++lga]=nvl;
Euler[lga]=nod;
}
return;
}
//M[i][j]=pozitia elementului minim in vectorul A din subsecventa care incepe la i si are lungimea 2^j
void precalculare()
{
int i, j;
for (log2lga=0, j=1; j<lga; j*=2, ++log2lga);
//if ((1<<log2lga)-lga) --log2lga;
for (i=1; i<=lga; ++i)
M[i][0]=i;
for (j=1; j<=log2lga; ++j)
for (i=1; i+(1<<j)-1<=lga; ++i)
if (A[M[i][j-1]]<A[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];
return;
}
int query (int st, int dr)
{
int lg, log2lg, ct;
lg=dr-st+1;
for (log2lg=0, ct=1; ct<lg; ct*=2, ++log2lg);
if ((1<<log2lg)-lg) --log2lg;
if (A[M[st][log2lg]] < A[M[dr-(1<<log2lg)+1][log2lg]])
return M[st][log2lg];
else
return M[dr-(1<<log2lg)+1][log2lg];
}
void rez()
{
int i, a, b;
for (i=1; i<=m; ++i)
{
fscanf(fin, "%d %d", &a, &b);
if (first[a]<first[b])
fprintf(fout, "%d\n", Euler[query (first[a], first[b])]);
else
fprintf(fout, "%d\n", Euler[query (first[b], first[a])]);
}
fclose(fin);
fclose(fout);
return;
}