Cod sursa(job #1513361)

Utilizator ionut98Bejenariu Ionut Daniel ionut98 Data 29 octombrie 2015 13:42:09
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.39 kb
#include<fstream>
#include<vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n,m,k;
vector<int>q[100005];
int l[100005],h[100005],lg[100005],v[100005];
int rmq[20][100005];
void dfs(int nod,int inaltime)
{
    k++;
    h[k]=nod;
    l[k]=inaltime;
    v[nod]=k;
    for(typeof(q[nod]).begin()it=(q[nod]).begin();it!=(q[nod]).end();++it)
    {
        dfs(*it,inaltime+1);
        k++;
        h[k]=nod;
        l[k]=inaltime;
    }
}
void Rmq()
{
    for(int i=2;i<=k;++i)
      lg[i]=lg[i>>1]+1;
    for(int i=1;i<=k;++i)
      rmq[0][i]=i;
    for(int i=1;(1<<i)<k;++i)
      for(int j=1;j<=k-(1<<i);++j)
      {
          int ll=1<<(i-1);
          rmq[i][j]=rmq[i-1][j];
          if(l[rmq[i-1][j+ll]]<l[rmq[i][j]])
            rmq[i][j]=rmq[i-1][j+ll];
      }
}
int lca(int x,int y)
{
    int diff,sol,sh;
    int a=v[x],b=v[y];
    if(a>b)
      swap(a,b);
    diff=b-a+1;
    int ll=lg[diff];
    sol=rmq[ll][a];
    sh=diff-(1<<ll);
    if(l[sol]>l[rmq[ll][a+sh]])
        sol=rmq[ll][a+sh];
    return h[sol];
}
int main()
{
    int x,y;
    f>>n>>m;
    for(int i=2;i<=n;i++)
    {
        f>>x;
        q[x].push_back(i);
    }
    dfs(1,0);
    //for(int i=1;i<=k;i++)
      //g<<h[i]<<" "<<l[i]<<"\n";
    Rmq();
    while(m)
    {
        m--;
        f>>x>>y;
        g<<lca(x,y)<<"\n";
    }
    return 0;
}