Cod sursa(job #1537865)

Utilizator beatrice01Ferco Beatrice beatrice01 Data 28 noiembrie 2015 11:19:07
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.58 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

int euler[200005],lev[100005],first[100005], log[200005], rmq[18][200005], nod[18][200005],cnt=0,n,m;
vector <int> v[100005];

void dfs (int x)
{
    euler[++cnt]= x;
    first[x]= cnt;
    for( int i=0; i<v[x].size(); ++i )
      {
          lev[v[x][i]]= lev[x]+1;
          dfs(v[x][i]);
          euler[++cnt]= x;
      }
}

int lca (int x,int y)
{
    x= first[x];
    y= first[y];
    if (x>y ) swap (x,y);
    int dif= y-x+1;
    int p= log[dif];
    if (rmq[p][x]< rmq[p][ y-(1<<p)+1 ] )
      return nod[p][x];
   return nod[p][ y-(1<<p)+1]  ;
}

int main()
{
    fin>>n>>m;
    for(int i=2;i<=n;++i)
      {
          int el;
          fin>>el;
          v[el].push_back(i);
      }
     dfs(1);

     for(int i=2;i<=cnt;++i)
       log[i]=log[i/2]+1;
     for(int i=1;i<=cnt;++i)
       {
           rmq[0][i]= lev[euler[i]];
           nod[0][i]= euler[i];
       }
     for(int i=1; (1<<i)<=cnt; ++i )
     for(int j=1; j+(1<<i)-1<=cnt;++j )
       {
           if( rmq[i-1][j] < rmq[i-1][j+(1<<(i-1))] )
             {
                 rmq[i][j]= rmq[i-1][j];
                 nod[i][j]= nod[i-1][j];
             }
           else
             {
                 rmq[i][j]= rmq[i-1][j+(1<<(i-1))];
                 nod[i][j]= nod[i-1][j+(1<<(i-1))];
             }
       }

     while(m--)
    {
        int a, b;
        fin >> a >> b;
        fout << lca(a, b) << "\n";
    }
    return 0;
}