Pagini recente » Cod sursa (job #1712351) | Istoria paginii runda/abac/clasament | Cod sursa (job #521979) | Cod sursa (job #2719419) | Cod sursa (job #3033107)
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int nmax = 1e5 + 5;
int dp[18][nmax], depth[nmax], logaritm[nmax];
pair <long long, int> v[nmax];
vector <int> edge[nmax];
void dfs(int node, int parent)
{
depth[node] = depth[parent] + 1;
for(int i = 0; i < edge[node].size(); i++){
int child = edge[node][i];
if(child == parent)
continue;
dp[0][child] = node;
for(int j = 1; j < 20; j++){
if(dp[j - 1][dp[j - 1][child]] == 0)
break;
dp[j][child] = dp[j - 1][dp[j - 1][child]];
}
dfs(child, node);
}
}
int lca(int x, int y)
{
if(depth[x] < depth[y])
swap(x, y);
int diferenta = depth[x] - depth[y];
int lg = logaritm[depth[x]];
for(int i = 0; (1 << i) <= diferenta; i++)
if(diferenta & (1 << i))
x = dp[i][x];
if(x == y)
return x;
for(int i = lg; i >= 0; i--){
if(dp[i][x] != dp[i][y]){
x = dp[i][x];
y = dp[i][y];
}
}
return dp[0][x];
}
int main()
{
int n, m;
cin >> n >> m;
for(int i = 0; i < 18; i++)
if((1 << i) <= nmax)
logaritm[(1 << i)] = 1;
for(int i = 1; i <= nmax - 5; i++)
logaritm[i] = logaritm[i - 1] + logaritm[i];
for(int i = 2; i <= n; i++){
int x;
cin >> x;
edge[x].push_back(i);
edge[i].push_back(x);
}
depth[0] = -1;
dfs(1, 0);
while(m--){
int x, y;
cin >> x >> y;
cout << lca(x, y) << "\n";
}
/*int t;
cin >> t;
for(int i = 0; i < 18; i++)
if((1 << i) <= nmax)
logaritm[(1 << i)] = 1;
for(int i = 1; i <= nmax - 5; i++)
logaritm[i] = logaritm[i - 1] + logaritm[i];
while(t--){
int n;
cin >> n;
for(int i = 1; i <= n; i++){
cin >> v[i].first;
v[i].second = i;
}
sort(v + 1, v + n + 1);
for(int i = 1; i <= n - 1; i++){
int x, y;
cin >> x >> y;
edge[x].push_back(y);
edge[y].push_back(x);
}
depth[0] = -1;
dfs(1, 0);
bool ok = true;
//v[0] = {1, 1};
for(int i = 2; i <= n; i++){
int lowest = lca(v[i].second, v[i - 1].second);
int distanta = depth[v[i].second] + depth[v[i - 1].second] - 2 * depth[lowest];
if(v[i].first - v[i - 1].first < distanta or (distanta & 1) != ((v[i].first - v[i - 1].first) & 1)){
ok = false;
break;
}
}
cout << ok;
for(int i = 1; i <= n; i++){
for(int j = 0; j < 18; j++)
dp[j][i] = 0;
depth[i] = 0;
edge[i].clear();
}
}*/
return 0;
}