Cod sursa(job #976311)

Utilizator andrettiAndretti Naiden andretti Data 22 iulie 2013 23:21:12
Problema Lowest Common Ancestor Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.49 kb
#include<stdio.h>
#include<algorithm>
#include<vector>
#define pb push_back
#define maxn 100005
#define maxm 200010
#define lgn 20
using namespace std;

int n,m,nr;
int e[maxm],lev[maxn],pos[maxn];
int lg[maxm],s[lgn][maxm];
vector <int> l[maxn];

void read()
{
    int x;
    scanf("%d%d",&n,&m);
    for(int i=2;i<=n;i++)
    {
        scanf("%d",&x);
        l[x].pb(i);
    }
}

void dfs(int k,int lvl)
{
    lev[k]=lvl;
    e[++nr]=k; if(!pos[k]) pos[k]=nr;
    for(unsigned int i=0;i<l[k].size();i++)
     if(!lev[l[k][i]])
     {
         dfs(l[k][i],lvl+1);
         e[++nr]=k;
     }
}

void rmq()
{
    int i,j;
    for(i=1;i<=nr;i++) s[0][i]=e[i];
    lg[1]=0;
    for(i=2;i<=nr;i++) lg[i]=lg[i/2]+1;

    for(i=1;i<=lg[nr];i++)
     for(j=1;j+(1<<i)<nr;j++)
      if(lev[s[i-1][j]]<=lev[s[i-1][j+(1<<(i-1))]])
       s[i][j]=s[i-1][j];
      else
       s[i][j]=s[i-1][j+(1<<(i-1))];
}

void solve()
{
    int x,y,px,py;
    int k,sol;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        if(pos[y]<pos[x]) swap(x,y);
        px=pos[x]; py=pos[y];
        k=lg[py-px+1];

        if(lev[s[k][px]]<=lev[s[k][py-(1<<k)+1]])
         sol=s[k][px];
        else
         sol=s[k][py-(1<<k)+1];
        printf("%d\n",sol);
    }
}

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

    read();
    dfs(1,0);
    rmq();
    solve();

    fclose(stdin);
    fclose(stdout);
    return 0;
}