Cod sursa(job #2634570)

Utilizator popoviciAna16Popovici Ana popoviciAna16 Data 11 iulie 2020 15:04:02
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.32 kb
#include <fstream>
#include <vector>
using namespace std;

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

vector <int> v[100001];

int rmq[18][100001];
//rmq[i][j] = al 2^i-lea stramos al lui j
int niv[100001];

void dfs(int r)
{
    int i;
    for (i = 0; i<v[r].size(); i++)
    {
        niv[v[r][i]] = niv[r] + 1;
        dfs(v[r][i]);
    }
}

inline int lsb(int x)
{
    return x & (-x);
}

int query(int x, int y)
{
    if (niv[x] < niv[y])
        swap(x, y);
    //x e mai jos decat y
    int d = niv[x] - niv[y], l;
    for (l = 0; (1<<l) <= d; l++)
        if (d & (1<<l))
            x = rmq[l][x];
    if (x == y) //adica deja imi era x stramos al lui y
        return x;
    l = 0;
    while ((1<<l) <= niv[x])
        l++;
    while (l >= 0)
    {
        if (rmq[l][x] != 0 && rmq[l][x] != rmq[l][y])
        {
            x = rmq[l][x];
            y = rmq[l][y];
        }
        l--;
    }
    return rmq[0][x];
}

int main()
{
    int n, m, i, j, x, y;
    fin >> n >> m;
    for (i = 2; i<=n; i++)
    {
        fin >> rmq[0][i];
        v[rmq[0][i]].push_back(i);
    }
    niv[1] = 1;
    dfs(1);
    for (i = 1; (1<<i) <= n; i++)
        for (j = 1; j<=n; j++)
            rmq[i][j] = rmq[i-1][rmq[i-1][j]];
    for (i = 1; i<=m; i++)
    {
        fin >> x >> y;
        fout << query(x, y) << '\n';
    }
    return 0;
}