Cod sursa(job #2392707)

Utilizator serbandonceanSerban Doncean serbandoncean Data 30 martie 2019 12:12:40
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.87 kb
#include <bits/stdc++.h>
#define DMAX 100010
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector<int> a[DMAX];
int euler[2*DMAX];
bool da[DMAX];
void citire();

int M[2*DMAX][30];
bool este[DMAX];
void eulere(int start);
int level[2*DMAX];
int nreuler,nrnivel;
int n,m;
int ind[DMAX];
void creareRMQ();
int main()
{
    citire();
    return 0;
}
void citire()
{int x,y,k;
    int i,j;
    fin>>n>>m;
    for(i=2;i<=n;i++)
    {
        fin>>x;
        a[x].push_back(i);
    }

    level[0]=-1;

    eulere(1);

    nrnivel=nreuler;
    creareRMQ();
    for(i=1;i<=m;i++)
    {
        fin>>x>>y;

        if(ind[x]<ind[y])

        {
            k=log2(ind[y]-ind[x]+1);
        if(level[M[ind[x]][k]]<=level[M[ind[y]-(1<<k)+1][k]])
            fout<<euler[M[ind[x]][k]]<<'\n';
        else
            fout<<euler[M[ind[y]-(1<<k)+1][k]]<<'\n';
        }
        else
        {
            k=log2(ind[x]-ind[y]+1);
        if(level[M[ind[y]][k]]<=level[M[ind[x]-(1<<k)+1][k]])
            fout<<euler[M[ind[y]][k]]<<'\n';
        else
            fout<<euler[M[ind[x]-(1<<k)+1][k]]<<'\n';

        }

    }
}
void eulere(int start)
{bool ok=0;
    int i;
    euler[++nreuler]=start;
    da[start]=1;
    level[nreuler]=level[nreuler-1]+1;
    if(!este[start])
        este[start]=1,ind[start]=nreuler;

    for(i=0;i<a[start].size();i++)
        if(!da[a[start][i]])
            {eulere(a[start][i]);
            euler[++nreuler]=start;
    level[nreuler]=level[nreuler-1]-1;
            }

}
void creareRMQ()
{
    int i,j;
    for(i=1;i<=nrnivel;i++)
        M[i][0]=i;
    for(j=1;(1<<j)<=nrnivel;j++)
        for(i=1;i+(1<<j)-1<=nrnivel;i++)
        if(level[M[i][j-1]]<level[M[i+(1<<(j-1))][j-1]])
            M[i][j]=M[i][j-1];
        else
            M[i][j]=M[i+(1<<(j-1))][j-1];
}