Cod sursa(job #1197046)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 10 iunie 2014 15:51:37
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.25 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#define pb push_back
#define N 100000+10
//#define abs(x) ((x)<0?-(x):(x))

int abs(int x){

return (x<0?-x:x);
}

using namespace std;

vector <int> g[N];
int n,m,i,t[N],niv[N*2],lg[N*2],r[N*2],j,x,y,nr,e[N*2],d[20][N*2],k;


bool poz[N];

void dfs(int x,int nv)
 {
     r[++nr]=x; niv[nr]=nv;
     if (!poz[x]) poz[x]=true, e[x]=nr;
     for (int i=0;i<g[x].size();++i)
      {
          dfs(g[x][i],nv+1);
          r[++nr]=x; niv[nr]=nv;
      }
 }

 void rmq()
 {
     for (i=1;i<=lg[nr];++i)
      for (j=1;j<=nr-(1<<(i-1));++j) d[i][j]=min(d[i-1][j], d[i-1][j+(1<<(i-1))]);
 }

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

    scanf("%d %d", &n, &m);
    for (i=1;i<n;++i) scanf("%d", &t[i]);
    for (i=1;i<n;++i)
       g[t[i]].pb(i+1);

    dfs(1,0);

    lg[1]=0;
    for (i=2;i<=N*2-10;++i) lg[i]=lg[i/2]+1;
    for (i=1;i<=nr;++i) d[0][i]=r[i];
    rmq();
    for (i=1;i<=m;++i)
     {
         scanf("%d %d", &x, &y);
         k=lg[abs(e[y]-e[x])+1];

         int ue=min(e[x],e[y]);
         int ut=max(e[x],e[y]);

         printf("%d\n", min(d[k][ue], d[k][ut-(1<<k)+1]));

     }


    return 0;
}