Cod sursa(job #1550454)

Utilizator dobrebogdanDobre Bogdan Mihai dobrebogdan Data 13 decembrie 2015 19:18:11
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include<cstdio>
#include<vector>
using namespace std;
vector<int> fii[100005];
int l,eu[200005],lv[100005],lg[200005],pr[100005],p2[25];
int rm[19][200005];
void dfs(int x)
{
    int i;
    l++;
    eu[l]=x;
    pr[x]=l;
    for(i=fii[x].size()-1;i>=0;i--)
    {
                lv[fii[x][i]]=lv[x]+1;
        dfs(fii[x][i]);
        l++;
        eu[l]=x;
    }
}
int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    int n,m,i,j,x,y,z;
    scanf("%d%d",&n,&m);
    for(i=2;i<=n;i++)
    {
        scanf("%d",&x);
        fii[x].push_back(i);
    }
    l=0;
    lv[1]=1;
    dfs(1);
    lg[1]=0;
    for(i=2;i<=l;i++)
        lg[i]=lg[i/2]+1;
    for(i=0;i<=18;i++)
    {
        if(i==0)
        {
            for(j=1;j<=l;j++)
            rm[i][j]=eu[j];
        }
        else
        {
        x=(1<<i);
        for(j=l-x+1;j>=1;j--)
        {
            if(lv[rm[i-1][j]]<lv[rm[i-1][j+x/2]])
                rm[i][j]=rm[i-1][j];
            else
                rm[i][j]=rm[i-1][j+x/2];
        }
        }
    }
        p2[0]=1;
    for(i=1;i<=19;i++)
        p2[i]=p2[i-1]*2;
    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        if(pr[x]>pr[y])
        {
            z=x;x=y;y=z;
        }
        z=pr[y]-pr[x]+1;
        if(lv[rm[lg[z]][pr[x]]]<lv[rm[lg[z]][pr[y]-p2[lg[z]]+1]])
        printf("%d\n",rm[lg[z]][pr[x]]);
        else
            printf("%d\n",rm[lg[z]][pr[y]-p2[lg[z]]+1]);
    }
    return 0;
}