Pagini recente » Cod sursa (job #321720) | Cod sursa (job #2718949) | Cod sursa (job #998086) | Cod sursa (job #797076) | Cod sursa (job #2029486)
#include <fstream>
#include <vector>
// SOLUTIA 4 - HEAVY+STRAMOSI
using namespace std;
const int MaxN = 1e5 + 1e3;
ifstream f("lca.in");
ofstream g("lca.out");
int lantdenod[MaxN], sub[MaxN], tata[MaxN], nivel_lant[MaxN], logg[MaxN], poz[MaxN], lanturi = 0, sz = 0, maxim = 0;
vector <int> gr[MaxN];
vector <int> lant[MaxN];
int dp[20][MaxN];
void dfs1(int node){
sub[node] = 1;
int best = 0;
for(auto x : gr[node]){
dfs1(x);
sub[node] += sub[x];
if(sub[best] < sub[x]){
best = x;
}
}
if(gr[node].size() == 0){
lanturi ++;
lantdenod[node] = lanturi;
lant[lanturi].push_back(node);
poz[node] = 0;
return;
}
lantdenod[node] = lantdenod[best];
lant[lantdenod[node]].push_back(node);
poz[node] = lant[lantdenod[node]].size() - 1;
}
void dfs2(int node){
if(poz[node] == lant[lantdenod[node]].size()-1){
++sz;
nivel_lant[lantdenod[node]] = sz;
maxim = max(maxim, sz);
}
dp[0][node] = tata[lant[lantdenod[node]].back()];
for(auto x : gr[node]){
dfs2(x);
}
if(poz[node] == lant[lantdenod[node]].size()-1){
--sz;
}
}
int LCA(int x, int y){
int lx = lantdenod[x], ly = lantdenod[y];
if(nivel_lant[lx] < nivel_lant[ly]) swap(x, y);
lx = lantdenod[x], ly = lantdenod[y];
int dif = nivel_lant[lx] - nivel_lant[ly];
for(int put = logg[dif]+1; put >= 0; --put){
if((1<<put) <= dif){
dif -= (1<<put);
x = dp[put][x];
}
}
lx = lantdenod[x];
if(lx == ly){
if(poz[x] > poz[y]) return x;
return y;
}
for(int put = logg[nivel_lant[lx]]+1; put >= 0; -- put){
if((1<<put) < nivel_lant[lx] && lantdenod[dp[put][x]] != lantdenod[dp[put][y]]){
x = dp[put][x];
y = dp[put][y];
lx = lantdenod[x];
}
}
x = dp[0][x];
y = dp[0][y];
if(poz[x] > poz[y]) return x;
return y;
}
int main(){
int n, m;
f >> n >> m;
tata[1] = 0;
for(int i = 2; i <= n; ++ i){
int a;
f >> a;
tata[i] = a;
gr[a].push_back(i);
logg[i] = logg[i>>1]+1;
}
dfs1(1);
dfs2(1);
for(int j = 1; j <= logg[maxim] + 1; ++ j){
for(int i = 1; i <= n; ++ i){
dp[j][i] = dp[j-1][dp[j-1][i]];
}
}
for(int i = 0; i < m; ++ i){
int a, b;
f >> a >> b;
g << LCA(a, b) << '\n';
}
return 0;
}