Cod sursa(job #2397924)

Utilizator Vlad_lsc2008Lungu Vlad Vlad_lsc2008 Data 4 aprilie 2019 21:23:35
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.84 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;

int n,q,h,sq;
int tata[100010],parinte_buck[100010],buck[100010],nivelu[100010];
vector<int> m[100010];

int nr_niv;

int dfs_niv(int nod,int nivel)
{
    nivelu[nod]=nivel;
    if(nivel>nr_niv) nr_niv=nivel;
    for(int i=0;i<m[nod].size();i++)
        dfs_niv(m[nod][i],nivel+1);
}

int dfs(int nod,int nivel)
{
    //cout<<nod<<' '<<nivel<<' '<<tata[nod]<<' '<<buck[tata[nod]]<<'\n';
    if( nivel > buck[ tata[nod] ]*sq )
    {
        buck[nod]=buck[ tata[nod]]+1;
        parinte_buck[nod]= tata[nod];
    }
    else
    {
        buck[nod]=buck[tata[nod]];
        parinte_buck[nod]= parinte_buck[ tata[nod]];
    }

    for(int i=0;i<m[nod].size();i++)
        dfs(m[nod][i],nivel+1);
}

int main()
{
    ifstream t1("lca.in");
    ofstream t2("lca.out");

    t1>>n>>q;

    int i,j;
    for(i=1;i<n;i++)
    {
        t1>>tata[i+1];
        m[tata[i+1]].push_back(i+1);
    }

    dfs_niv(1,1);
    sq=sqrt(nr_niv);

    dfs(1,1);

    int st,dr;

    for(i=1;i<=q;i++)
    {
        t1>>st>>dr;
        while( parinte_buck[st]!=parinte_buck[dr])
        {
            if( buck[st]<buck[dr]) dr=parinte_buck[dr];
            else if( buck[dr]<buck[st]) st=parinte_buck[st];
                 else
                 {
                     dr=parinte_buck[dr];
                     st=parinte_buck[st];
                 }
        }
        while( st!=dr )
        {

            if(nivelu[st]<nivelu[dr]) dr=tata[dr];
            else if(nivelu[st]>nivelu[dr]) st=tata[st];
                 else
                 {
                    dr=tata[dr];
                    st=tata[st];
                 }
        }

        t2<<st<<'\n';
    }

    t1.close();
    t2.close();
    return 0;
}