Cod sursa(job #2577698)

Utilizator dimi999Dimitriu Andrei dimi999 Data 9 martie 2020 19:02:50
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.7 kb
#include <bits/stdc++.h>
using namespace std;

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

int ap[100005], dads[100005], nivel[100005], pw[200005];

struct elem
{
    int niv, poz;
}v[200005], rmq[200005][20];

vector <int> g[100005];

int n, m, k;

void dfs(int node)
{
    nivel[node] = nivel[dads[node]] + 1;
    v[++k].niv = nivel[node];
    v[k].poz = node;

    for(int i = 0; i < g[node].size(); i++)
    {
        dfs(g[node][i]);
        v[++k].niv = nivel[node];
        v[k].poz = node;
    }
}

void rmqlca()
{
    for(int i = 1; i <= k; i++)
        rmq[i][0] = v[i];

    pw[1] = 0;

    for(int i = 2; i <= k; i++)
            pw[i] = pw[i/2] + 1;

    int q = 1;

    for(int p = 1; p * 2 <= k; p *= 2)
    {
        for(int i = 1; i <= k - p*2 + 1; i++)
            if(rmq[i][q - 1].niv < rmq[i + p][q - 1].niv)
                rmq[i][q] = rmq[i][q-1];
            else
                rmq[i][q] = rmq[i + p][q - 1];

        q++;
    }
}

int lca(int a, int b)
{
    a = ap[a];
    b = ap[b];

    if(a > b)
        swap(a, b);

    int l = b - a + 1;

    if(rmq[a][pw[l]].niv < rmq[b - (1<<pw[l]) + 1][pw[l]].niv)
        return rmq[a][pw[l]].poz;
    else
        return rmq[b - (1<<pw[l]) + 1][pw[l]].poz;
}

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

    for(int i = 2; i <= n; i++)
        {
            fin >> dads[i];
            g[dads[i]].push_back(i);
        }

    dfs(1);
    rmqlca();

    for(int i = 1; i <= k; i++)
        if(ap[v[i].poz] == 0)
            ap[v[i].poz] = i;

    for(int i = 1; i <= m; i++)
    {
        int x, y;

        fin >> x >> y;

        fout << lca(x,y) << '\n';
    }
    return 0;
}