Cod sursa(job #2392497)

Utilizator onipreponiprep oniprep Data 30 martie 2019 09:12:22
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.31 kb
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int N=100009,LOGN=log2(2*N)+1;
int n,k;
int rmq[2*N][LOGN],euler[2*N],first[N],l[2*N];
vector <int> v[N];
void dfs(int nod,int lvl)
{
    euler[++euler[0]]=nod;
    first[nod]=euler[0];
    l[euler[0]]=lvl;
    for(int i=0;i<v[nod].size();i++)
    {
        dfs(v[nod][i],lvl+1);
        euler[++euler[0]]=nod;
        l[euler[0]]=lvl;
    }
}
void Rmq()
{
    for(int i=1;i<=euler[0];i++)
       rmq[i][0]=i;
    for(int j=1;j<=log2(euler[0])+1;j++)
        for(int i=1;i<=euler[0]&&i+(1<<j)<=euler[0]+1;i++)
        {
            rmq[i][j]=rmq[i][j-1];
            if(l[rmq[i][j-1]]>l[rmq[i+(1<<(j-1))][j-1]])
                rmq[i][j]=rmq[i+(1<<(j-1))][j-1];
        }
}
void lca(int x,int y)
{
    x=first[x],y=first[y];
    if(x>y)
        swap(x,y);
    int put=log2(y-x+1);
    int ans=min(euler[rmq[x][put]],euler[rmq[y-(1<<put)+1][put]]);
    fout<<ans<<'\n';
}
void solve()
{
    dfs(1,1);
    Rmq();
    while(k)
    {
        k--;
        int x,y;
        fin>>x>>y;
        lca(x,y);
    }
}
int main()
{
    fin>>n>>k;
    for(int i=1;i<n;i++)
    {
        int x;
        fin>>x;
        v[x].pb(i+1);
    }
    solve();
    return 0;
}