Cod sursa(job #2397910)

Utilizator Vlad_lsc2008Lungu Vlad Vlad_lsc2008 Data 4 aprilie 2019 21:18:04
Problema Lowest Common Ancestor Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.92 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 nr;
int solve(int st,int dr)
{
   // cout<<st<<' '<<dr<<'\n';
    if( buck[st]>buck[dr] ) return solve( parinte_buck[st], dr);
    if( buck[st]<buck[dr]) return solve( st, parinte_buck[dr]);

    if( parinte_buck[st]==parinte_buck[dr] )
    {
        while( st!=dr )
        {
            if(nr>15) break;
          //  cout<<st<<' '<<dr<<'\n';
            if(nivelu[st]<nivelu[dr]) dr=tata[dr];
            else if(nivelu[st]>nivelu[dr]) st=tata[st];
                 else
                 {
                    dr=tata[dr];
                    st=tata[st];
                 }
        }
        return st;
    }
    else return solve( parinte_buck[st],parinte_buck[dr] );
}

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;
        t2<<solve(st,dr)<<'\n';
    }

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