Pagini recente » Cod sursa (job #943567) | Rating Daniel Babiceanu (Daniel25031) | Istoria paginii runda/iiiiiiiiii | Istoria paginii runda/bravo_1 | Cod sursa (job #1934852)
#include <iostream>
#include <fstream>
#include <vector>
#include <climits>
#include <queue>
#include <cmath>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int NMax = 1e5 + 5;
const int inf = 1e9;
#define foreach(V) for(typeof (V).begin() it = (V).begin(); it != (V).end(); ++it)
int N,M,nrEuler;
int euler[2*NMax],poz[NMax],depth[NMax],
lg[2*NMax],mn[2*NMax][20];
vector<int> v[NMax];
void doEuler(int,int);
int main() {
in>>N>>M;
int mx = 0;
for (int i=2;i<=N;++i) {
int dad;
in>>dad;
v[dad].push_back(i);
if (mx < dad) {
mx = dad;
}
}
//cout<<mx<<'\n';
doEuler(1,1);
//cout<<nrEuler<<'\n';
for (int i=1;i<=nrEuler;++i) {
int n1 = euler[i-1],
n2 = euler[i],
d1 = depth[n1],
d2 = depth[n2];
if (abs(d1-d2) > 1 || d2 <= 0) {
cout<<euler[i]<<'\n';
}
}
/*
for (int i=1;i<=nrEuler;++i) {
out<<i<<' ';
}
out<<'\n';
for (int i=1;i<=nrEuler;++i) {
out<<euler[i]<<' ';
}
out<<"\n\n";
for (int i=1;i<=N;++i) {
out<<i<<' ';
}
out<<'\n';
for (int i=1;i<=N;++i) {
out<<depth[i]<<' ';
}
out<<'\n';
for (int i=1;i<=N;++i) {
out<<poz[i]<<' ';
}
out<<'\n';
//*/
lg[1] = 0;
mn[1][0] = euler[1];
for (int i=2;i<=nrEuler;++i) {
lg[i] = lg[i/2] + 1;
//out<<i<<' '<<lg[i]<<'\n';
mn[i][0] = euler[i];
}
//out<<"\n\n\n";
for (int p=1;(1<<p) <= nrEuler;++p) {
for (int i=1;i + (1<<p) - 1 <= nrEuler;++i) {
int nod1 = mn[i][p-1],
nod2 = mn[i + (1<<(p-1))][p-1];
if (depth[nod1] < depth[nod2]) {
mn[i][p] = nod1;
}
else {
mn[i][p] = nod2;
}
}
}
/*
for (int i=2;i<=nrEuler;++i) {
out<<i<<' '<<lg[i]<<'\n';
}
out<<"\n\n\n";
*/
while (M--) {
int a,b;
in>>a>>b;
if (poz[a]>poz[b]) {
swap(a,b);
}
int i = poz[a], j = poz[b],
p = lg[j-i+1],
nod1 = mn[i][p],
nod2 = mn[j - (1<<p) + 1][p];
int ans;
if (depth[nod1] < depth[nod2]) {
ans = nod1;
}
else {
ans = nod2;
}
out<<ans<<'\n';
}
return 0;
}
void doEuler(int x,int d) {
euler[++nrEuler] = x;
poz[x] = nrEuler;
depth[x] = d;
int lim = v[x].size();
for (int i=0;i<lim;++i) {
int son = v[x][i];
doEuler(son,d+1);
euler[++nrEuler] = x;
}
}