Cod sursa(job #2605763)

Utilizator cezarinfoTulceanu Cezar cezarinfo Data 25 aprilie 2020 19:08:23
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
FILE*in=fopen("lca.in","r");
FILE*out=fopen("lca.out","w");
int n,m,i,j,k,ar,vec,po[100],l,lg,x,y,ras,len;
struct deep
{
    int n,d;
};
deep ad,pd[100][1000003];
int dep=0;
int first[1000010];
vector<int> v[1000010];
vector<deep> euler;
int log(int a)
{
    int st=0,dr=i,mij;
    while(st<dr-1)
    {
        mij=(st+dr)/2;
        if(po[mij]<=a)
        {
            st=mij;
        }
        else if(po[mij]>a)
        {
            dr=mij;
        }
    }
    while(po[mij]<a)
    {
        mij++;
    }
    while(po[mij]>=a)
    {
        mij--;
    }
    return mij;
}
void DFS(int n)
{
    dep++;
    ad.n=n;
    ad.d=dep;
    len=euler.size();
    if(first[n]==0&&n!=1)
    {
        first[n]=len;
    }
    pd[0][len].d=dep;
    pd[0][len].n=n;
    euler.push_back(ad);
    for(int j=0;j<v[n].size();j++)
    {
        vec=v[n][j];
        DFS(vec);
        dep--;
        ad.n=n;
        ad.d=dep;
        len=euler.size();
        pd[0][len].d=dep;
        pd[0][len].n=n;
        euler.push_back(ad);
    }
}
int main()
{
    fscanf(in,"%d%d",&n,&m);
    for(i=2;i<=n;i++)
    {
        fscanf(in,"%d",&ar);
        v[ar].push_back(i);
    }
    DFS(1);
    l=euler.size();
    po[0]=1;
    for(i=1;2*po[i-1]<=l;i++)
    {
        po[i]=po[i-1]*2;
    }
    i--;
    for(j=1;j<=i;j++)
    {
        for(k=0;k<=l-po[j];k++)
        {
            if(pd[j-1][k].d<=pd[j-1][k+po[j-1]].d)
            {
                pd[j][k].d=pd[j-1][k].d;
                pd[j][k].n=pd[j-1][k].n;
            }
            else
            {
                pd[j][k].d=pd[j-1][k+po[j-1]].d;
                pd[j][k].n=pd[j-1][k+po[j-1]].n;
            }
        }
    }
    for(j=1;j<=m;j++)
    {
        fscanf(in,"%d%d",&x,&y);
        x=first[x];
        y=first[y];
        if(x==y)
        {
            fprintf(out,"%d\n",pd[0][x].n);
            continue;
        }
        if(y<x)
        {
            swap(x,y);
        }
        lg=log(y-x+1);
        if(pd[lg][x].d<=pd[lg][y-po[lg]+1].d)
        {
            ras=pd[lg][x].n;
        }
        else
        {
            ras=pd[lg][y-po[lg]+1].n;
        }
        fprintf(out,"%d\n",ras);
    }
}