Pagini recente » Cod sursa (job #976866) | Cod sursa (job #1761265) | Cod sursa (job #2624868) | Cod sursa (job #2949851) | Cod sursa (job #2180525)
#include <fstream>
#include <vector>
#include <cmath>
#include <bitset>
#define Nmax 100009
#define Logmax 18
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n,m,s[Logmax][Nmax],x,y,d[Nmax];
vector <int> G[Nmax];
void build_ancestor(int kmax) {
s[0][1]=0;
for (int i=2; i<=n; ++i) {
f>>x;
s[0][i]=x;
G[x].push_back(i);
}
for (int k=1; k<=kmax; ++k)
for (int i=1; i<=n; ++i) {
s[k][i] = s[ k-1 ][ s[k-1][i] ];
}
}
int get_ancestor(int x, int p) {
int kmax=log2(p);
for (int k=0; k<=kmax; ++k) {
if (p & 1) {
x = s[k][x];
}
p >>= 1;
}
return x;
}
int LCA(int x, int y) {
if (d[x]>d[y]) {
x = get_ancestor(x, d[x]-d[y]);
}
else if (d[y]>d[x]) {
y = get_ancestor(y, d[y]-d[x]);
}
int k=0;
int a=x;
int b=y;
while(a!=b){
a=s[k][x];
b=s[k][y];
if (a==b && k==0) return a;
else if (a==b && k!=0) {
a=s[k-1][x];
b=s[k-1][y];
x=s[k-1][x];
y=s[k-1][y];
k=0;
}
else if (a!=b) ++k;
}
return a;
}
void DFS(int node) {
for (auto x: G[node]) {
d[x]=d[node]+1;
DFS(x);
}
}
void Solve() {
f>>n>>m;
int kmax= log2(n);
build_ancestor(kmax);
DFS(1);
for (int querry=1; querry<=m; ++querry) {
f>>x>>y;
if (x==y) g<<x<<'\n';
else g<<LCA(x,y)<<'\n';
}
}
int main() {
Solve();
f.close(); g.close();
return 0;
}