Cod sursa(job #2922066)

Utilizator Theo14Ancuta Theodor Theo14 Data 3 septembrie 2022 16:33:51
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.66 kb
#include<bits/stdc++.h>
#define int long long
using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

int n,m,w[100005],nivel[100005],k,e[200005],p[200005],ap[200005];
vector<int>v[100005];

struct elem
{
    int x,niv;
};
elem nou[2*100005];
elem rmq[20][2*100005];

void dfs(int nod)
{
    nivel[nod]=nivel[w[nod]]+1;
    k++;
    nou[k].x=nod;
    nou[k].niv=nivel[nod];
    for(auto it:v[nod])
    {
        dfs(it);
        k++;
        nou[k].x=nod;
        nou[k].niv=nivel[nod];
    }
}

void rmqprecalc()
{
    int i,x,k1;
    for(i=1;i<=k;i++)
        rmq[0][i]=nou[i];
    x=1,k1=0;
    for(i=1;i<=k;i++)
    {
        if(i==2*x)
        {
            k1++;
            x*=2;
        }
        e[i]=k1;
        p[k1]=x;
    }
    x=2;k1=1;
    while(x<=n)
    {
        for(i=1;i<=k-x+1;i++)
        {
            if(rmq[k1-1][i].niv<rmq[k1-1][i+x/2].niv)
                rmq[k1][i]=rmq[k1-1][i];
            else
                rmq[k1][i]=rmq[k1-1][i+x/2];
        }
        k1++;
        x*=2;
    }
}

int lca(int x, int y)
{
    x=ap[x];
    y=ap[y];
    if(x>y)
        swap(x,y);
    int l=y-x+1;
    if(rmq[e[l]][x].niv<rmq[e[l]][y-p[e[l]]+1].niv)
        return rmq[e[l]][x].x;
    else
        return rmq[e[l]][y-p[e[l]]+1].x;
}

signed main()
{
    int i,x,y;
    f>>n>>m;
    for(i=2;i<=n;i++)
    {
        f>>w[i];
        v[w[i]].push_back(i);
    }
    dfs(1);
    rmqprecalc();
    for(i=1;i<=k;i++)
    {
        if(ap[nou[i].x]==0)
            ap[nou[i].x]=i;
    }
    for(i=1;i<=m;i++)
    {
        f>>x>>y;
        g<<lca(x,y)<<'\n';
    }
    return 0;
}