Cod sursa(job #2085934)

Utilizator vladcoroian2001Vlad Coroian vladcoroian2001 Data 10 decembrie 2017 22:00:25
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.37 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fi("lca.in");
ofstream fo("lca.out");
const int nmax=1e5+5,INF=(1<<30);
int n,m,a,b,x,nivel[nmax],lvl_euler[3*nmax],euler[3*nmax],first[nmax],ctr,dp[3*nmax][20];
vector <int> v[nmax];
void explore(int x)
{
    euler[++ctr]=x;
    if(first[x]==0)
        first[x]=ctr;
    for(auto y:v[x])
    {
        explore(y);
        euler[++ctr]=x;
    }
}
int sol(int x,int y)
{
    if(x>y)
        swap(x,y);
    int d=y-x+1;
    int k=0;
    while((1<<(k+1))<=d)
        k++;
    return min(dp[x][k],dp[y-(1<<k)+1][k]);
}
int main()
{
    fi>>n>>m;
    nivel[1]=0;
    for(int i=2;i<=n;i++)
    {
        fi>>x;
        nivel[i]=nivel[x]+1;
        v[x].push_back(i);
    }
    explore(1);
    for(int i=1;i<=ctr;i++)
        lvl_euler[i]=nivel[euler[i]];

    for(int j=1;(1<<j)<=ctr;j++)
        for(int i=1;i<=ctr;i++)
            dp[i][j]=INF;

    for(int i=1;i<=ctr;i++)
        dp[i][0]=euler[i];
    for(int j=1;(1<<j)<=ctr;j++)
        for(int i=1;i<=ctr;i++)
            if(nivel[dp[i][j-1]]<nivel[dp[i+(1<<(j-1))][j-1]])
                dp[i][j]=dp[i][j-1];
            else
                dp[i][j]=dp[i+(1<<(j-1))][j-1];

    for(int i=1;i<=m;i++)
    {
        fi>>a>>b;
        fo<<sol(first[a],first[b])<<"\n";
    }
    fi.close();
    fo.close();
    return 0;
}