Cod sursa(job #2343157)

Utilizator tigeraOprea Tereza Emilia tigera Data 13 februarie 2019 18:45:57
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.41 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

int n, m, x, y, poz;

vector <int> fii[100010];
int v[200010], pap[100010];
int log2[200010];
int rmq[23][200010];
int h[100010];

void euler (int nod, int hl)
{
    v[++poz] = nod;
    rmq[0][poz] = nod;
    pap[nod] = poz;
    h[nod] = hl;
    for (auto it : fii[nod])
    {
        euler(it, hl+1);
        v[++poz] = nod;
        rmq[0][poz] = nod;
    }
}

int minn (int st, int dr)
{
    int dist = log2[dr - st + 1];
    if (h[rmq[dist][st]] < h[rmq[dist][dr-(1<<dist) + 1]])
        return rmq[dist][st];
    else
        return rmq[dist][dr-(1<<dist) + 1];
}

int main()
{
    fin >> n >> m;
    for (int i=2; i<=n; i++)
    {
        fin >> x;
        fii[x].push_back(i);
    }
    poz = 0;
    euler(1, 1);
    for (int i=2; i<=2*n-1; i++)
        log2[i] = log2[i/2]+1;
    for (int i=1; i<=23; i++)
    {
        for (int j=1; j<=2*n-1; j++)
        {
            if ( j+ (1 << (i-1)) > 2*n-1)
                break;
            if ( h[rmq[i-1][j]] < h[rmq[i-1][j+ (1 << (i-1))]])
                rmq[i][j] = rmq[i-1][j];
            else
                rmq[i][j] = rmq[i-1][j+ (1 << (i-1))];
        }
    }
    for (int i=1; i<=m; i++)
    {
        fin >> x >> y;
        if (pap[x] > pap[y])
            swap(x, y);
        fout << minn(pap[x], pap[y]) << '\n';
    }
        
    return 0;
}