Cod sursa(job #999101)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 19 septembrie 2013 11:11:38
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.94 kb
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

vector<int> vecini[100005];
int euler[200010],n;
int h[200010];
int l[100005];
int poz;
int hul;
int din[18][200010];
int log2[200010];

void pre_log()
{
    int i=2,aux=(2*n-1);
    log2[1]=0;
    for(;i<=aux;i++)
       log2[i]=log2[i/2]+1;
}

void precalc()
{
    int i,aux=2*n-1;
    int ln=log2[aux],j;
    for(i=1;i<=aux;i++)
        din[0][i]=i;
    for(i=1;i<=ln;i++)
    {
        for(j=1;j<=aux;j++)
        {
            if((j+((1<<i)-1))<=aux)
            {
                if(h[din[i-1][j]]<h[din[i-1][j+(1<<(i-1))]])
                    din[i][j]=din[i-1][j];
                else
                    din[i][j]=din[i-1][j+(1<<(i-1))];
            }
        }
    }
}

void dfs(int nod)
{
    euler[poz]=nod;
    if(!l[nod])
        l[nod]=poz;
    h[poz++]=hul++;

    vector<int>::iterator it;
    for(it=vecini[nod].begin();it!=vecini[nod].end();it++)
    {
        dfs(*it);
        h[poz]=--hul;
        euler[poz++]=nod;
        hul++;
    }
    hul--;
}



int main()
{
    ifstream cin("lca.in");
    ofstream cout("lca.out");

    int m=0,x,i,a,b,ln,c,d;
    cin>>n>>m;
    for(i=2;i<=n;i++)
    {
        cin>>x;
        vecini[x].push_back(i);
    }
    hul=0;
    dfs(1);
    pre_log();
    precalc();
   // cout<<"jop"<<endl;
    for(i=0;i<m;i++)
    {
        cin>>a>>b;

       // cout<<"a este "<<a<<endl;
        a=l[a];
      //  cout<<"b este "<<b<<endl;
        b=l[b];
        if(a>b)
            swap(a,b);
        ln=log2[b-a+1];
        c=din[ln][a];
       // cout<<"c e "<<c<<endl;
        d=din[ln][b-(1<<ln)+1];
       // cout<<"d e "<<d<<endl;
        if(h[c]<h[d])
        {
             cout<<euler[c]<<'\n';
        }
        else
        {
             cout<<euler[d]<<'\n';
        }
    }


    cin.close();
    cout.close();
    return 0;
}