Cod sursa(job #2607357)

Utilizator rares9991Matisan Rares-Stefan rares9991 Data 29 aprilie 2020 17:23:22
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.55 kb
#include <fstream>
#define L 17
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[N], prima[N], rmq[L][2*N], nc, nivel[N], rez, log2[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;
        }
    }
}

void log (int n)
{
    log2[1]=0;
    for (int i=2;i<=2*n-1;i++)
    {
        log2[i]=log2[i/2]+1;
    }
}

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;
    }
    log(n);
    dfs(1);
    for(int j=1; j<=n; 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;
}