Cod sursa(job #1184952)

Utilizator ArchazeyBaltatu Andrei-Mircea Archazey Data 14 mai 2014 18:29:28
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.13 kb
#include<fstream>
#include<vector>
#include<bitset>
using namespace std;

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

int n,m,a[100005],Euler[200005],lg,nivel[200005],puteri[25],logaritm[200005];
int mat[200005][20],aparitii[100005];
vector<int>v[100005];
bitset<100005>viz;

inline void DFS(int x,int niv)
{
    int i,len;
    nivel[x]=niv;
    len=v[x].size();
    for (i=0;i<len;i++)
        DFS(v[x][i],niv+1);
}

inline void ParcurgereEuler(int x)
{
    int i,len;
    if (!viz[x]) {aparitii[x]=lg+1;viz[x]=1;}
    len=v[x].size();
    for (i=0;i<len;i++)
        {
            Euler[++lg]=x;
            ParcurgereEuler(v[x][i]);
        }
    Euler[++lg]=x;
}

inline void RMQ()
{
    int i,aux,put;
    mat[lg][0]=Euler[lg];
    for (i=lg-1;i>=1;i--)
        {
            if (nivel[Euler[i]]<nivel[Euler[i+1]]) mat[i][0]=Euler[i];
            else mat[i][0]=Euler[i+1];
            aux=lg-i;
            put=1;
            while (puteri[put]<=aux)
                {
                    if (nivel[mat[i][put-1]]<nivel[mat[i+puteri[put-1]][put-1]]) mat[i][put]=mat[i][put-1];
                    else mat[i][put]=mat[i+puteri[put-1]][put-1];
                    put++;
                }
        }
    logaritm[2]=1;
    for (i=3;i<=200000;i++)
        logaritm[i]=logaritm[i>>1]+1;
}

inline void Rezolva()
{
    int i,x,y,aux,st,dr;
    while (m--)
        {
            fin>>x>>y;
            st=min(aparitii[x],aparitii[y]);
            dr=max(aparitii[x],aparitii[y]);
            aux=dr-st;
            if (nivel[mat[st][logaritm[aux]]]<nivel[mat[dr-puteri[logaritm[aux]]][logaritm[aux]]])
                fout<<mat[st][logaritm[aux]];
            else fout<<mat[dr-puteri[logaritm[aux]]][logaritm[aux]];
            fout<<"\n";
        }
}

int main()
{
    int i;
    fin>>n>>m;
    for (i=1;i<=n-1;i++)
        {
            fin>>a[i];
            v[a[i]].push_back(i+1);
        }
    puteri[0]=1;
    puteri[1]=2;
    for (i=1;i<=22;i++)
        puteri[i]=puteri[i-1]<<1;
    DFS(1,1);
    ParcurgereEuler(1);
    RMQ();
    Rezolva();
    fout<<"\n";
    return 0;
}