Cod sursa(job #3140555)

Utilizator Raul_AArdelean Raul Raul_A Data 7 iulie 2023 08:25:46
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.7 kb
#include <bits/stdc++.h>
#define cin in
#define cout out
#define eb emplace_back
#define pii pair<int,int>
#define tpl tuple<int,int,int>
#define fi first
#define se second
using namespace std;

const string file_name("lca");

ifstream in(file_name + ".in");
ofstream out(file_name + ".out");

int n,q,x,y,rmq[21][200005],Log[200005],niv[100005],cnt,st[100005];
vector<int> euler,g[100005];
bitset<100005> v;

void read();
void dfs(int k);
void init();
int QueryRmq(int x,int y);
void solve();

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    read();
    euler.eb(0);
    dfs(1);
    init();
    while(q--)
        solve();
    return 0;
}

void read()
{
    cin>>n>>q;
    for(int i=2;i<=n;i++)
        cin>>x,g[x].eb(i);
}

void dfs(int k)
{
    v[k]=1;
    euler.eb(k);
    cnt++;
    st[k]=cnt;

    for(auto x: g[k])
        if(!v[x])
        {
            niv[x]=niv[k]+1;
            dfs(x);
            euler.eb(k);
            cnt++;
        }
}

void init()
{
    Log[1]=0;
    rmq[0][1]=euler[1];

    for(int i=2;i<=cnt;i++)
        rmq[0][i]=euler[i],Log[i]=Log[i/2]+1;

    for(int i=1;(1<<i)<=cnt;i++)
        for(int j=(1<<i);j<=cnt;j++)
        {
            int k=1<<(i-1);
            rmq[i][j]=rmq[i-1][j];

            if(niv[rmq[i-1][j-k]]<niv[rmq[i-1][j]])
                rmq[i][j]=rmq[i-1][j-k];
        }
}

int QueryRmq(int x,int y)
{
    int k=Log[y-x+1];
    int ans=rmq[k][x+(1<<k)-1];

    if(niv[rmq[k][y]]<niv[ans])
        ans=rmq[k][y];
    return ans;
}

void solve()
{
    cin>>x>>y;

    x=st[x],y=st[y];

    if(x>y) swap(x,y);

    cout<<QueryRmq(x,y)<<'\n';
}