Cod sursa(job #2607374)

Utilizator rares9991Matisan Rares-Stefan rares9991 Data 29 aprilie 2020 17:35:13
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <fstream>
#define L 20
using namespace std;

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

const int N=100001;
const int M=2*N;
const int P=2000001;

int lst[N], urm[2*M], vf[2*M], nr, e[2*N-1], prima[N], rmq[L][2*N], nc, nivel[N], rez, log2[2*N], t[N];

int n, m;

void adauga(int x, int y)
{
    vf[++nr]=y;
    urm[nr]=lst[x];
    lst[x]=nr;
}

void dfs(int x)
{
    e[++nc]=x;
    nivel[x]=1+nivel[t[x]];
    prima[x]=nc;
    for (int p=lst[x]; p!=0; p=urm[p])
    {
        int y=vf[p];
        if (prima[y]==0)
        {
            dfs(y);
            e[++nc]=x;
        }
    }
}


int lca(int x, int y)
{
    rez=0;
    int px=prima[x];
    int py=prima[y];
    if(px>py)
        swap(px,py);
    int l=log2[py-px+1];
    int rez=rmq[l][px+(1<<l)-1];
    if(nivel[rmq[l][py]]<nivel[rez])
        rez=rmq[l][py];
    return rez;
}

int main()
{
    in>>n>>m;
    for(int i=2; i<=n; i++)
    {
        int x;
        in>>x;
        adauga(x, i);
        t[i]=x;
    }
    for(int i = 2; i <= 2*n; i++)
        log2[i] = 1 + log2[i/2];
    dfs(1);
    for(int j=1; j<=nc; j++)
        rmq[0][j]=e[j];
    for(int i=1; i<L; i++)
        for(int j=1<<i; j<=2*n-1; j++)
        {
            rmq[i][j]=rmq[i-1][j];
            int x=rmq[i-1][j-(1<<(i-1))];
            if(nivel[x]<nivel[rmq[i][j]])
                rmq[i][j]=x;
        }
    while(m)
    {
        m--;
        int a,b;
        in>>a>>b;
        out<<lca(a,b)<<"\n";
    }
    return 0;
}