Cod sursa(job #1425884)

Utilizator andreey_047Andrei Maxim andreey_047 Data 28 aprilie 2015 12:47:41
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.76 kb
#include <cstdio>
#include <vector>
#define nmax 100005
using namespace std;
vector<int>G[nmax];
vector<int>::iterator it;
int n,m,H[nmax*2+28],lev[nmax],f[nmax];
int lg[nmax];

struct Coord{
 int x,poz;
}rmq[20][nmax*2];

inline void Euler(int niv,int x){
    H[++H[0]] = x;
    lev[H[0]] = niv;
    f[x] = H[0];
    for(int i = 0 ; i < G[x].size();++i){
        Euler(niv+1,G[x][i]);
        H[++H[0]] = x;
        lev[H[0]] = niv;
    }
}
inline void LCA(){
 int i,j,l;
    for(i = 2; i <= H[0]; ++i)
        lg[i] = lg[i/2]+1;
  for (i=1;i<=H[0];i++)
  {
      rmq[0][i].x=lev[i];
      rmq[0][i].poz = i;
  }
   for (i=1; (1 << i) <=H[0]; i++)
    for (j=(1<<i);j <=H[0]; j++)
        {
           l=1<<(i-1);
           if(rmq[i-1][j].x <= rmq[i-1][j-l].x)
           {
               rmq[i][j].x = rmq[i-1][j].x;
               rmq[i][j].poz = rmq[i-1][j].poz;
           }
           else
           {
               rmq[i][j].x = rmq[i-1][j-l].x;
               rmq[i][j].poz = rmq[i-1][j-l].poz;
           }
        }
//        for(i = 1;i <= H[0]; ++i)
//        printf("%d ",H[i]);
//    printf("\n");
//    for(i = 1;i <= H[0]; ++i)
//        printf("%d ",lev[i]);
//    printf("\n");
}
int main(){
    int i,x,y,l,s;
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d %d\n",&n,&m);
    for(i = 1; i < n; ++i){
        scanf("%d ",&x);
        G[x].push_back(i+1);
    }
    Euler(0,1);
    LCA();
    while(m--){
        scanf("%d %d\n",&x,&y);
        x = f[x];
        y = f[y];
        l = lg[y-x+1];
        if(rmq[l][x-1+(1<<l)].x <= rmq[l][y].x)
            s = rmq[l][x-1+(1<<l)].poz;
        else s = rmq[l][y].poz;
        printf("%d\n",H[s]);
    }
    return 0;
}