Pagini recente » Cod sursa (job #1399277) | Cod sursa (job #331405) | Cod sursa (job #3198127) | Cod sursa (job #2905330) | Cod sursa (job #575926)
Cod sursa(job #575926)
#include <fstream>
#include <vector>
#define pb push_back
#define TR(C, i)\
for(typeof(C.begin()) i = C.begin(); i != C.end(); i++)
using namespace std;
const int nmax = 100100;
int N, M, RMQ[20][nmax << 2], Lg[nmax << 1];
vector <int> A[nmax];
ifstream in("lca.in");
void read()
{
in >> N >> M;
int i, a;
for(i = 2; i <= N; i++)
{
in >> a;
A[a].pb( i );
}
}
int H[nmax << 1], V[nmax << 1], cat;
int First[nmax];
void euler(int nod, int lev)
{
H[++cat] = lev;
V[cat] = nod;
First[nod] = cat;
TR(A[nod], it)
{
euler(*it, lev + 1);
V[++cat] = nod;
H[cat] = lev;
}
}
void create()
{
euler(1, 1);
int i, j, up;
for(i = 2; i <= cat; i++)
Lg[i] = Lg[i >> 1] + 1;
for(i = 1; i <= cat; i++)
RMQ[0][i] = i;
for(i = 1; (1 << i) < cat; i++)
for(j = 1; j <= cat - (1 << i); j++)
{
up = 1 << (i - 1);
RMQ[i][j] = RMQ[i - 1][j];
if(H[RMQ[i][j]] > H[RMQ[i - 1][j + up]])
RMQ[i][j] = RMQ[i - 1][j + up];
}
}
int lca(int a, int b)
{
if(First[a] > First[b])
swap(a, b);
int diff = First[b] - First[a] + 1;
int lg = Lg[diff];
int add = diff - (1 << lg);
int Mic = RMQ[lg][First[a]];
if(H[Mic] > H[RMQ[lg][First[a] + add]])
Mic = RMQ[lg][First[a] + diff - (1 << lg)];
return V[Mic];
}
void query()
{
ofstream out("lca.out");
int i, a, b;
for(i = 1; i <= M; i++)
{
in >> a >> b;
out << lca(a, b) << '\n';
}
}
int main()
{
read();
create();
query();
return 0;
}