Cod sursa(job #2574037)

Utilizator DariusDCDarius Capolna DariusDC Data 5 martie 2020 20:05:13
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.58 kb
#include <bits/stdc++.h>

using namespace std;

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

const int nmax = 100005;
int n, m;
vector <int> g[nmax];
int euler[2*nmax], nivel[2*nmax], primap[nmax], k;
int sp[2*nmax][30];

inline void read()
{
    fin >> n >> m;
    for (int i = 2; i <= n; i++)
    {
        int a;
        fin >> a;
        g[a].push_back(i);
    }
}

inline void dfs(int nod,int tata, int niv)
{
    euler[++k] = nod;
    nivel[k] = niv;
    if (primap[nod] == 0)
        primap[nod] = k;
    for (auto fiu : g[nod])
    {
        if (fiu == tata)
            continue;
        dfs(fiu, nod, niv+1);
        euler[++k] = nod;
        nivel[k] = niv;
    }
}

inline int rmq(int a, int b)
{
    if (b < a)
        swap(a, b);
    int l = b-a+1;
    int k = log2(l)+1;
    if (nivel[sp[a][k]] < nivel[sp[b - (1 << (k-1))+1][k]])
        return sp[a][k];
    return sp[b-(1 << (k-1))+1][k];
}

inline void gettable()
{
    dfs(1, 0, 1);
    for (int i = 1; i <= k; i++)
        sp[i][1] = i;
    for (int j = 2; (1 << (j-1)) <= k; j++)
        for (int i = 1; i + (1 << (j-1)) - 1 <= k; i++)
            if (nivel[sp[i][j-1]] < nivel[sp[i + (1 << (j-2))][j-1]])
                sp[i][j] = sp[i][j-1];
            else
                sp[i][j] = sp[i+(1 << (j-2))][j-1];
}

inline int lca(int a, int b)
{
    return euler[rmq(primap[a], primap[b])];
}

int main()
{
    read();
    gettable();
    while (m--)
    {
        int a, b;
        fin >> a >> b;
        fout << lca(a, b) << "\n";
    }
    return 0;
}