Pagini recente » Cod sursa (job #1635604) | Cod sursa (job #3282796) | Cod sursa (job #1533925) | Cod sursa (job #412183) | Cod sursa (job #2453833)
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
int n, m, lanturi;
vector<int> graf[MAXN], hpd[MAXN];
int v[MAXN], tata[MAXN], nivelLant[MAXN], lant[MAXN], pos[MAXN], sub[MAXN];
int dp[MAXN][30], lg[MAXN];
void HPD_init(int nod){
sub[nod] = 1;
for(auto x:graf[nod]){
HPD_init(x);
sub[nod] += sub[x];
}
if(sub[nod] == 1){
lanturi++;
hpd[lanturi].push_back(nod);
lant[nod] = lanturi;
return;
}
int best = 0;
for(auto x:graf[nod]){
if(sub[best] < sub[x])
best = x;
}
lant[nod] = lant[best];
hpd[lant[best]].push_back(nod);
pos[nod] = (int)hpd[lant[best]].size() - 1;
}
int niv;
void StramosiInit(int nod){
if(pos[nod] == 0){
niv++;
nivelLant[lant[nod]] = niv;
}
dp[nod][0] = tata[hpd[lant[nod]][0]];
for(auto x:graf[nod])
StramosiInit(x);
if(pos[nod] == 0) niv--;
}
int solve(int x, int y){
int lx = lant[x], ly = lant[y];
if(nivelLant[lx] < nivelLant[ly]){
swap(x, y);
swap(lx, ly);
}
int dif = nivelLant[lx] - nivelLant[ly];
for(int p = lg[dif] + 1; p >= 0; --p){
if((1 << p) <= dif){
dif -= (1 << p);
x = dp[x][p];
}
}
lx = lant[x];
if(lx == ly){
if(pos[x] < pos[y]) return x;
return y;
}
for(int p = lg[nivelLant[lx]] + 1; p >= 0; --p){
if(nivelLant[lx] > (1 << p) && lant[dp[x][p]] != lant[dp[y][p]]){
x = dp[x][p];
y = dp[y][p];
lx = lant[x];
}
}
x = dp[x][0];
y = dp[y][0];
if(pos[x] < pos[y]) return x;
return y;
}
int main()
{
ifstream fin("lca.in");
ofstream fout("lca.out");
fin >> n >> m;
for(int i = 2; i <= n; ++i){
fin >> tata[i];
graf[tata[i]].push_back(i);
lg[i] = lg[i / 2] + 1;
}
HPD_init(1);
for(int i = 1; i <= lanturi; ++i) reverse(hpd[i].begin(), hpd[i].end());
for(int i = 1; i <= n; ++i) pos[i] = (int)hpd[lant[i]].size() - 1 - pos[i];
StramosiInit(1);
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= 20; ++j)
dp[i][j] = dp[dp[i][j - 1]][j - 1];
}
while(m){
int x, y;
fin >> x >> y;
fout << solve(x, y) << "\n";
m--;
}
return 0;
}