Pagini recente » Cod sursa (job #1339171) | Cod sursa (job #2457502) | Cod sursa (job #2429745) | Diferente pentru problema/take5 intre reviziile 6 si 4 | Cod sursa (job #2422478)
#include <bits/stdc++.h>
#define nmax 100005
#define pb push_back
using namespace std;
int peuler[nmax*2], ap[nmax], h[nmax*2];
int rmq[nmax*2][50];
int n, inalt, m, x, act, y;
vector<int>g[nmax];
void dfs(int k)
{
peuler[++act] = k;
h[act] = inalt;
ap[k] = act;
for (auto x:g[k])
{
++inalt;
dfs(x);
--inalt;
peuler[++act] = k;
h[act] = inalt;
}
}
int l2(int x) // log2(x)
{
if (x<=1) return 0;
int ans = 0, p2 = 1;
while(true)
{
if (p2>x) return ans-1;
++ans, p2*=2;
}
}
void rmqq()
{
for (int i=1;i<=act;++i)
rmq[i][0] = i;
for (int j=1;(1<<j) <= act; ++j)
for (int i=1;i + (1<<j) -1 <=act;++i)
if (h[rmq[i][j-1]] < h[rmq[i+(1<<(j-1))][j-1]])
rmq[i][j] = rmq[i][j-1];
else
rmq[i][j] = rmq[i+(1<<(j-1))][j-1];
}
int lca(int x, int y)
{
int ap1 = ap[x];
int ap2 = ap[y];
if (ap1 > ap2) swap(ap1, ap2);
int dist = ap2 - ap1 + 1;
int lg2 = l2(dist);
int add = dist - (1<<lg2);
if (h[rmq[ap1][lg2]] <= h[rmq[ap1+add][lg2]])
return peuler[rmq[ap1][lg2]];
else
return peuler[rmq[ap1+add][lg2]];
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%d %d",&n,&m);
for (int i=2;i<=n;++i)
{
scanf("%d",&x);
g[x].pb(i);
}
dfs(1);
rmqq();
for (int i=1;i<=m;++i)
{
scanf("%d %d",&x,&y);
printf("%d\n", lca(x, y));
}
fclose(stdin);
fclose(stdout);
return 0;
}