Pagini recente » Cod sursa (job #665153) | Cod sursa (job #84921) | Cod sursa (job #1892758) | Cod sursa (job #2631001) | Cod sursa (job #2886176)
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int nmax = 3e5 + 5;
int rmq[20][nmax], inveuler[nmax], depth[nmax];
pair <int, int> v[nmax];
vector <int> euler;
vector <int> edge[nmax];
bool cmp(pair <int, int> a, pair <int, int> b)
{
return a.first < b.first;
}
void dfs(int node, int father)
{
depth[node] = depth[father] + 1;
euler.push_back(node);
for(int i = 0; i < edge[node].size(); i++){
if(edge[node][i] == father)
continue;
dfs(edge[node][i], node);
euler.push_back(node);
}
}
void rmqcalc()
{
depth[0] = nmax + 5;
int i, j;
for(i = 0; i < euler.size(); i++){
rmq[0][i] = euler[i];
inveuler[euler[i]] = i;
}
for(j = 1; (1 << j) <= euler.size(); j++)
for(i = 0; i + (1 << j) + 1 <= euler.size(); i++){
if(depth[rmq[j - 1][i]] > depth[rmq[j - 1][i + (1 << (j - 1))]])
rmq[j][i] = rmq[j - 1][i + (1 << (j - 1))];
else
rmq[j][i] = rmq[j - 1][i];
}
}
int lca(int a, int b)
{
a = inveuler[a];
b = inveuler[b];
if(a == b)
return rmq[0][a];
if(a > b)
swap(a, b);
int len = b - a + 1;
int lg = 31 - __builtin_clz(len);
if(depth[rmq[lg][a]] > depth[rmq[lg][b - (1 << lg) + 1]])
return rmq[lg][b - (1 << lg) + 1];
else
return rmq[lg][a];
}
void reinitializare()
{
int maxx = 0, i, j;
for(j = 1; (1 << j) <= euler.size(); j++)
for(i = 0; i + (1 << j) + 1 <= euler.size(); i++)
rmq[j][i] = 0;
for(i = 0; i < euler.size(); i++){
inveuler[euler[i]] = 0;
depth[euler[i]] = 0;
maxx = max(maxx, euler[i]);
}
for(i = 0; i <= maxx; i++)
edge[i].clear();
euler.clear();
}
int main()
{
int n, i, j, t, q;
cin >> n >> q;
for(i = 2; i <= n; i++){
int x;
cin >> x;
edge[i].push_back(x);
edge[x].push_back(i);
}
dfs(1, 1);
rmqcalc();
for(i = 1; i <= q; i++){
int a, b;
cin >> a >> b;
cout << lca(a, b) << "\n";
}
/*cin >> t;
while(t--){
cin >> n;
bool ok = true;
for(i = 1; i <= n; i++)
cin >> v[i].first, v[i].second = i;
for(i = 1; i <= n - 1; i++){
int x, y;
cin >> x >> y;
edge[x].push_back(y);
edge[y].push_back(x);
}
dfs(1, 1);
rmqcalc();
/*int q;
cin >> q;
for(i = 1; i <= q; i++){
int a, b;
cin >> a >> b;
cout << lca(a, b) << "\n";
}
sort(v + 1, v + n + 1, cmp);
for(i = 2; i <= n; i++){
if(v[i].first == v[i - 1].first){
ok = false;
break;
}
int x = lca(v[i].second, v[i - 1].second);
if(depth[v[i].second] - depth[x] + depth[v[i - 1].second] - depth[x] > v[i].first - v[i - 1].first){
ok = false;
break;
}
}
cout << ok;
reinitializare();
}*/
return 0;
}