Cod sursa(job #1527185)

Utilizator elevenstrArina Raileanu elevenstr Data 17 noiembrie 2015 21:46:50
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.79 kb
#include <bits/stdc++.h>

using namespace std;
#define MAX 100008
ofstream out("lca.out");
stack <int> S;
vector <int> v[MAX];
int lg[MAX*3],mat[30][MAX*4],first[MAX],lvl[MAX*2],eul[MAX*2];
int k=0;
char buff[10000];
const int DIM=10000;
int poz=0;
FILE * fil=fopen("lca.in","r");
inline void citire(int &nr)
{ nr=0;
while (!isdigit(buff[poz]))
{
    ++poz;
    if(poz==DIM)
    {fread(buff,1,DIM,fil);poz=0;}
}

while(isdigit(buff[poz]))
{  nr=nr*10+buff[poz]-'0';
   ++poz;
   if(poz==DIM)
    {fread(buff,1,DIM,fil);poz=0;}
}
}
inline void dfs(int nod, int lev)
{
    eul[++k]=nod;
    first[nod]=k;
    lvl[k]=lev;
    for(vector <int> ::iterator it=v[nod].begin(); it!=v[nod].end(); it++)
        if(first[*it]==0)
        {
            dfs(*it,lev+1);
            eul[++k]=nod;
            lvl[k]=lev;
        }
}

inline void rmq(int n)
{
    int el=lg[n];
    int i,j;
    for(i=1; i<=lg[n]; i++)
        for(j=1; j<=n-(1<<i); j++)
            if(lvl[mat[i-1][j]]<lvl[mat[i-1][j+(1<<(i-1))]])
                mat[i][j]=mat[i-1][j];
            else mat[i][j]=mat[i-1][j+(1<<(i-1))];

}
inline int lca(int a,int b)
{
    int n1=first[a],n2=first[b],i,j,x;
    if(n1>n2)swap(n1,n2);
    int el=lg[n2-n1+1];
    if(lvl[mat[el][n1]]>lvl[mat[el][n2-(1<<el)+1]])
        return eul[mat[el][n2-(1<<el)+1]];
    else return eul[mat[el][n1]];

}
int main()
{
    int n,m,i,j,a,b;
    for(i=2; i<=MAX*2; i++)
        lg[i]=lg[i/2]+1;
    citire(n);
    citire(m);
    for(i=2; i<=n; i++)
    {
        citire(a);
        v[a].push_back(i);
    }
    dfs(1,1);
    for(i=1; i<=k; i++)
        mat[0][i]=i;

    rmq(k);
    for(i=1; i<=m; i++)
    {
        citire(a);
        citire(b);
        out<<lca(a,b)<<'\n';
    }


    return 0;
}