Cod sursa(job #1209200)

Utilizator Adrian1997Radulescu Adrian Adrian1997 Data 17 iulie 2014 12:29:07
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.29 kb
#include<fstream>
#include<vector>
#include<cmath>
using namespace std;
#define NMAX 100005
ifstream fin("lca.in");
ofstream fout("lca.out");
vector <int> v[NMAX];
int n,m,k,T[NMAX],E[NMAX*2],N[NMAX*2],F[NMAX],a[23][NMAX*2],p[NMAX*2];
void dfs(int s, int niv)
{
    int i;
    E[++k]=s;
    N[k]=niv;
    if (!F[s]) F[s]=k;
    for (i=0;i<v[s].size();++i)
    {
        dfs(v[s][i],niv+1);
        E[++k]=s, N[k]=niv;
    }
}

int main()
{
    int i,b,x,y,j;
    fin>>n>>m;
    for (i=2;i<=n;++i)
    {
        fin>>T[i];
        v[T[i]].push_back(i);
    }
    dfs(1,1);

    p[1]=0,a[0][1]=1;
    for(i=2;i<=k;i++)
        p[i]=1+p[i/2],a[0][i]=i;

    for(i=1;(1<<i)<=k;i++){
        //calculam linia i care corespunde secventei de lungime 2^i din matrice
        for(j=1;j<=k;j++){
            a[i][j]=a[i-1][j];
            if((1<<(i-1))+j<=k && N[a[i-1][(1<<(i-1))+j]]<N[a[i][j]] )
                a[i][j]=a[i-1][(1<<(i-1))+j];
        }
    }

    for(i=1;i<=m;i++){
        fin>>x>>y;
        x=F[x],y=F[y];
        if(x>y) b=x,x=y,y=b;
        b=p[y-x+1];
        if(N[a[b][x]]<=N[a[b][y-(1<<b)+1]])
            fout<<E[a[b][x]];
        else fout<<E[a[b][y-(1<<b)+1]];
        fout<<"\n";
    }

    fin.close();
    fout.close();
    return 0;
}