Cod sursa(job #2964608)

Utilizator Zed1YasuoAlex Birsan Zed1Yasuo Data 13 ianuarie 2023 13:50:30
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.53 kb
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int N=1e5+3;
int n,m,X,Y,q,apar[N],v[N],rmq[2*N][20];
vector<int>a[N];
struct eu
{
    int val,etaj;
};
vector<eu>euler;
void dfs(int nod,int etaj)
{
    v[nod]=1;
    apar[nod]=euler.size();
    euler.push_back({nod,etaj});
    for(auto x : a[nod])
        if(!v[x])
        {
            dfs(x,etaj+1);
            euler.push_back({nod,etaj});
        }
}
void build_rmq()
{
    for(int i=0;i<m;i++)
        rmq[i][0]=i;
    int lg=log2(m);
    for(int i=1;i<=lg;i++)
    {
        int put=1<<i;
        for(int j=0;j+put<m;j++)
        {
            int left=rmq[j][i-1];
            int right=rmq[j+put/2][i-1];

            if(euler[left].etaj>euler[right].etaj)
                rmq[j][i]=right;
            else
                rmq[j][i]=left;
        }
    }
}
int query(int x, int y)
{
    if(apar[x]>apar[y])
        swap(x,y);
    int lg=log2(apar[y]-apar[x]+1),sl;
    int st=rmq[apar[x]][lg];
    int dr=rmq[apar[y]-(1<<lg)+1][lg];
    if(euler[st].etaj>euler[dr].etaj)
        sl=dr;
    else
        sl=st;
    return euler[sl].val;
}
int main()
{
    f>>n>>q;
    for(int i=2;i<=n;i++)
    {
        f>>X;
        a[X].push_back(i);
    }
    dfs(1,0);
    m=euler.size();
 //   for(int i=1;i<=n;i++)
 //       g<<apar[i]<<" ";
    build_rmq();
    for(int i=1;i<=q;i++)
    {
        f>>X>>Y;
        g<<query(X,Y)<<'\n';
    }
    return 0;
}