Cod sursa(job #2977227)

Utilizator CobzaruAntonioCobzaru Paul-Antonio CobzaruAntonio Data 11 februarie 2023 09:45:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.51 kb
#include <fstream>
#include <vector>
#define pb push_back
using namespace std;
ifstream cin ("lca.in");
ofstream cout ("lca.out");
int n,m,s;
int e[200005];
int d[200005];
int f[100005];
int rmq[200005][20];
vector<int> g[100005];
void dfs (int n,int l)
{
    e[++s] = n;
    d[s] = l;
    f[n] = s;
    for (auto vf:g[n])
    {
        dfs(vf,l+1);
        e[++s] = n;
        d[s] = l;
    }
}
void construieste()
{
    int i,j,vmax = 0;
    for (i=0;(1<<i)<=s;i++)
        vmax = i;
    for (i=1;i<=s;i++)
        rmq[i][0] = i;
    for (j=1;j<=vmax;j++)
        for(i=1;i+(1<<j)-1 <= s;i++)
            if (d[rmq[i][j-1]] < d[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 answ;
    int dist,p;
    x = f[x];
    y = f[y];
    if (x > y)
        swap(x,y);
    dist = y - x + 1;
    for (p=0;(1<<p)<=dist;p++)
        continue;
    p--;
    int f1 = rmq[x][p];
    int f2 = rmq[y-(1<<p)+1][p];
    if (d[f1] < d[f2])
        answ = f1;
    else
        answ = f2;
    return e[answ];
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    int i;
    for (i=2;i<=n;i++)
    {
        int x;
        cin >> x;
        g[x].pb(i);
    }
    dfs(1,0);
    construieste();
    for (i=1;i<=m;i++)
    {
        int l,r;
        cin >> l >> r;
        cout << lca(l,r) << '\n';
    }
    return 0;
}