Cod sursa(job #3003087)

Utilizator CobzaruAntonioCobzaru Paul-Antonio CobzaruAntonio Data 15 martie 2023 14:21:56
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream cin ("lca.in");
ofstream cout ("lca.out");
int n,m,s;
int e[400005],l[400005],u[100005];
int rmq[25][400005],f[100005];
int lg[400005];
vector<int> g[100005];
void euler (int vf,int lvl)
{
    u[vf] = true;
    e[++s] = vf;
    f[vf] = s;
    l[s] = lvl;
    for (auto nod:g[vf])
    {
        if (u[nod])
            continue;
        euler(nod,lvl+1);
        e[++s] = vf;
        l[s] = lvl;
    }
}
void rmq1 ()
{
    for(int i=2;i<=s;i++)
        lg[i] = lg[i/2] + 1;
    for(int i = 1;i<=s;i++)
        rmq[0][i] = i;
    for (int i=1;(1<<i)<=s;i++)
        for(int j=1;j+(1<<i)-1<=s;j++)
        {
            if (l[rmq[i-1][j]] < l[rmq[i-1][j+(1<<(i-1))]])
            {
                rmq[i][j] = rmq[i-1][j];
                continue;
            }
            rmq[i][j] = rmq[i-1][j+(1<<(i-1))];
        }
}
int lca (int x,int y)
{
    x = f[x];
    y = f[y];
    if (x>y)
        swap(x,y);
    int d = y - x + 1;
    int i = lg[d];
    if (l[rmq[i][x]] < l[rmq[i][y-(1<<i)+1]])
        return e[rmq[i][x]];
    return e[rmq[i][y-(1<<i)+1]];
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    for (int i=2;i<=n;i++)
    {
        int x;
        cin >> x;
        g[x].push_back(i);
    }
    euler(1,1);
    rmq1();
    for (int q=1;q<=m;q++)
    {
        int x,y;
        cin >> x >> y;
        cout << lca(x,y) << '\n';
    }
    return 0;
}