Pagini recente » Cod sursa (job #1866961) | Cod sursa (job #2899859) | Cod sursa (job #2464264) | Cod sursa (job #437377) | Cod sursa (job #2437953)
#include<bits/stdc++.h>
#pragma gcc optimize("O3")
#define all(s) s.begin(),s.end()
#define rc(x) return cout<<x<<endl,0
#define forn(i,n) for(int i=0;i<int(n);i++)
#define len(a) (int) (a).size()
#define pb push_back
#define mp make_pair
#define fr first
#define sc second
#define nmax 100005
typedef long long ll;
typedef long double ld;
const int mod=1e9+7;
const ll inf=0x3f3f3f3f3f3f3f3f;
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector < int > E[nmax << 1], Ind_First(nmax << 1, 0), Log(nmax << 1, 0);
vector < pair < int, int > > Euler_Tour(nmax << 1);
int RMQ[20][nmax << 2], K = 0, n, m;
void Dfs(int node, int level)
{
Euler_Tour[++K].fr = node;
Euler_Tour[K].sc = level;
Ind_First[node] = K;
for (auto it : E[node])
{
Dfs(it, level + 1);
Euler_Tour[++K].fr = node;
Euler_Tour[K].sc = level;
}
}
void Range_Minimum_Query()
{
for (int i = 2; i <= K; i++)
Log[i] = Log[i / 2] + 1;
for (int i = 1; i <= K; i++)
RMQ[0][i] = i;
for (int i = 1; (1 << i) <= K; i++)
for (int j = 1; j <= K - (1 << i); j++)
{
int l = 1 << (i - 1);
RMQ[i][j] = RMQ[i - 1][j];
int y = Euler_Tour[RMQ[i - 1][j + l]].sc;
if (y < Euler_Tour[RMQ[i][j]].sc) RMQ[i][j] = RMQ[i - 1][j + l];
}
}
int LCA(int x, int y)
{
int a = Ind_First[x];
int b = Ind_First[y];
if (a > b) swap(a, b);
int d = b - a + 1;
int l = Log[d];
int x1 = d - (1 << l);;
int position = RMQ[l][a];
if (Euler_Tour[RMQ[l][a + x1]].sc < Euler_Tour[RMQ[l][a]].sc)
position = RMQ[l][a + x1];
return Euler_Tour[position].fr;
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
ios_base::sync_with_stdio(0); cin.tie(0);
fin >> n >> m;
for (int i = 2; i <= n; i++)
{
int x;
fin >> x;
E[x].pb(i);
}
Dfs(1, 0);
Range_Minimum_Query();
while (m--)
{
int x, y;
fin >> x >> y;
fout << LCA(x, y) << "\n";
}
}