Cod sursa(job #2576839)

Utilizator Bogdan2728Iamnitchi Bogdan Bogdan2728 Data 6 martie 2020 23:53:05
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.55 kb
#include <bits/stdc++.h>
#define Nmax 100005
#define Logm 20
using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

int n,m;
int depth[Nmax], first[Nmax];
int Rmq[Logm][2*Nmax], lg[2*Nmax];
vector<int> v[Nmax];
vector<int> euler;

void Read()
{
    f>>n>>m;
    for(int i=1,x;i<n;i++)
    {
        f>>x;
        v[x].push_back(i+1);
        v[i+1].push_back(x);
    }
}

void Dfs(int nodCurr,int nodTata)
{
    first[nodCurr] = euler.size();
    depth[nodCurr] = depth[nodTata] + 1;
    euler.push_back(nodCurr);
    for(auto& it : v[nodCurr])
    {
        if(it == nodTata)
            continue;
        Dfs(it,nodCurr);
        euler.push_back(nodCurr);
    }
}

void computeRmq()
{
    for(int i=2;i<2*Logm;i++)
        lg[i] = lg[i>>1] + 1;
    for(int i=0;i<euler.size();i++)
        Rmq[0][i] = euler[i];
    for(int i=1;i<Logm;i++)
        for(int j=0,k=(1<<i);k<euler.size();j++,k++)
            Rmq[i][j] = (depth[Rmq[i-1][j]] < depth[Rmq[i-1][j+(1<<(i-1))]] ? Rmq[i-1][j] : Rmq[i-1][j+(1<<(i-1))]);
}

int Lca(int x,int y)
{
    if(x == y)
        return x;
    int st = first[x];
    int dr = first[y];
    if(st > dr)
        swap(st,dr);
    int power = lg[dr -st +1];
    int c1 = Rmq[power][st];
    int c2 = Rmq[power][dr -(1<<power) +1];
    if(depth[c1] < depth[c2])
        return c1;
    return c2;
}

int main()
{

    Read();
    Dfs(1,0);
    computeRmq();
    for(int i=1,x,y;i<=m;i++)
    {
        f>>x>>y;
        g<<Lca(x,y)<<"\n";
    }
    g.close();
    return 0;
}