Cod sursa(job #2055073)

Utilizator georgerapeanuRapeanu George georgerapeanu Data 2 noiembrie 2017 20:11:35
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <iostream>
#include <map>
#include <cstring>
#include <cstdlib>
#include <vector>
#define rad 2000
using namespace std;
int N,M;
vector<int> G[100005];
int euler[200005];
int RMQ[15][200005];
int fst[100005];
int lst[100005];
int dep[100005];
int eulsz;
int lg[200005];
int calceuler(int nod,int tata)
{
   dep[nod]=1+dep[tata];
   euler[++eulsz]=nod;
   fst[nod]=eulsz;
   for(auto it:G[nod])
   {
      if(it!=tata)
      {
         calceuler(it,nod);
         euler[++eulsz]=nod;
      }
   }
   lst[nod]=eulsz;
}
void prelca()
{
   for(int i=2;i<=100000;i++)lg[i]=1+lg[i/2];
   for(int i=1;i<=eulsz;i++)
   {
      RMQ[0][i]=euler[i];
   }
   for(int k=1;k<=14;k++)
   {
      for(int i=1;i<=eulsz;i++)
      {
         int b=i,a=i-(1<<(k-1));
         if(a<=0)RMQ[k][i]=RMQ[k-1][i];
         else
         {
            int nod1=RMQ[k-1][a],nod2=RMQ[k-1][b];
            RMQ[k][i]=(dep[nod1]<dep[nod2] ? nod1:nod2);
         }
      }
   }
}
int lca(int a,int b)
{
   a=fst[a];b=fst[b];
   if(b<a)swap(a,b);
   int LG=lg[b-a+1];
   return dep[RMQ[LG][b]]<dep[RMQ[LG][a+(1<<LG)-1]] ? RMQ[LG][b]:RMQ[LG][a+(1<<LG)-1];
}
int main() {
    freopen("lca.in","r",stdin);cin.sync_with_stdio(false);cin.tie(0);
    freopen("lca.out","w",stdout);cout.sync_with_stdio(false);cout.tie(0);
    cin>>N>>M;
    for(int i=2;i<=N;i++)
    {
       int x;
       cin>>x;
       G[x].push_back(i);
       G[i].push_back(x);
    }
    calceuler(1,0);
    prelca();
    for(int i=1;i<=M;i++)
    {
        int x,y;
        cin>>x>>y;
        cout<<lca(x,y)<<"\n";
    }
    return 0;
}