Pagini recente » Cod sursa (job #2855290) | Cod sursa (job #2678783) | Cod sursa (job #314186) | Cod sursa (job #249999) | Cod sursa (job #2705579)
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int N_MAX = 1e5;
const int E_MAX = N_MAX << 2;
const int INF = 0x3f3f3f3f3f3f3f3f;
int n, q, eLen;
int log2[N_MAX + 10], fr[N_MAX + 10];
pair<int, int> rmq[E_MAX][21];
vector<pair<int, int>> e;
vector<vector<int>> adj;
void scan()
{
in >> n >> q;
adj.resize(n + 5);
for(int i = 2; i <= n; i++)
{
int x;
in >> x;
adj[x].push_back(i);
}
}
void euler(int node, int depth)
{
e.emplace_back(node, depth + 1);
for(auto it: adj[node])
{
euler(it, depth + 1);
e.emplace_back(node, depth + 1);
}
}
void calcRmq()
{
for(int i = 0; i < eLen; i++)
rmq[i][0] = e[i];
for(int p = 1; (1 << p) <= eLen; p++)
{
for(int i = 0; i < eLen; i++)
{
if(rmq[i][p - 1].second < rmq[i + (1 << (p - 1))][p - 1].second)
rmq[i][p] = rmq[i][p - 1];
else
rmq[i][p] = rmq[i + (1 << (p - 1))][p - 1];
}
}
}
int query(int x, int y)
{
//cout << x << ' ' << y << '\n';
int st = min(fr[x], fr[y]), fs = max(fr[x], fr[y]);
int d = fs - st + 1;
/*
cout << st << ' ' << fs << '\n';
cout << rmq[st][log2[d]].first << ' ' << rmq[st][log2[d]].second << '\n';
cout << rmq[fs - (1 << log2[d]) + 1][log2[d]].first << ' ' << rmq[fs - (1 << log2[d]) + 1][log2[d]].second << "\n\n";
*/
if(rmq[st][log2[d]].second < rmq[fs - (1 << log2[d]) + 1][log2[d]].second)
return rmq[st][log2[d]].first;
return rmq[fs - (1 << log2[d]) + 1][log2[d]].first;
}
int main()
{
scan();
euler(1, -1);
eLen = e.size();
memset(fr, INF, sizeof fr);
for(int i = 0; i < eLen; i++)
fr[e[i].first] = min(i, fr[e[i].first]);
log2[1] = 0;
for(int i = 2; i <= n; i++)
log2[i] = log2[i / 2] + 1;
calcRmq();
while(q--)
{
int x, y;
in >> x >> y;
out << query(x, y) << '\n';
}
return 0;
}