Cod sursa(job #2337897)

Utilizator alexilasiAlex Ilasi alexilasi Data 6 februarie 2019 19:39:36
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.47 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

const int nMax = 100000, logMax = 17;

int n,m,i,j,x,y,idx,loge,e;
int rmq[nMax + 10][logMax + 5];
int level[nMax + 10];
vector <int> v[nMax + 10], vertexes(nMax + 10), reverse_vertexes(nMax + 10), first_occurence(nMax + 10), euler;

void dfs(int vertex)
{
    vertexes[vertex] = ++idx;
    reverse_vertexes[idx] = vertex;

    euler.push_back(vertexes[vertex]);

    for(auto it : v[vertex])
        if(!vertexes[it])
        {
            dfs(it);
            euler.push_back(vertexes[vertex]);
        }
}

int getMin(int a,int b)
{
    int dist = b-a+1;
    int log = log2(dist);
    return min(rmq[a][log], rmq[b-(1<<log)+1][log]);
}


int main()
{
    fin>>n>>m;

    for(i=2; i<=n; i++)
    {
        fin>>x;
        v[x].push_back(i);
    }

    dfs(1);

    i=0;
    for(auto it : euler)
    {
        i++;
        if(!first_occurence[it]) first_occurence[it] = i;
    }

    e = euler.size();

    loge = floor(log2(e));

    for(i=1; i<=e; i++)
        rmq[i][0] = euler[i-1];

    for(j=1; j<=loge; ++j)
        for(i=1; i<= (e - (1<<j) + 1); ++i)
        {
            rmq[i][j] = min(rmq[i][j-1], rmq[i+(1<<(j-1))][j-1]);
        }

    for(i=1; i<=m; i++)
    {
        fin>>x>>y;
        fout<<reverse_vertexes[getMin(first_occurence[vertexes[x]], first_occurence[vertexes[y]])]<<'\n';
    }

    return 0;
}