Cod sursa(job #2388707)

Utilizator vladvlad00Vlad Teodorescu vladvlad00 Data 26 martie 2019 12:47:45
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
#include <fstream>
#include <vector>
#define pb push_back

using namespace std;

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

void DFS(int x);
void rmq();

int n, nr, m, nivel, niv[400005], poz[400005], nod[400005], uz[100005], A[100005][25];
vector<int> L[100005];

int main()
{
    int i, k, x, y, st, dr, a, b;

    fin >> n >> m;
    for (i=2;i<=n;i++)
    {
        fin >> x;
        L[x].pb(i);
        L[i].pb(x);
    }
    nivel = 0;
    DFS(1);
    rmq();
    for (i=1;i<=m;i++)
    {
        fin >> x >> y;
        if (poz[x] > poz[y])
            swap(x,y);
        st = poz[x];
        dr = poz[y];
        for (k=0;(1<<(k+1))<=(dr-st+1);k++);
        a = A[st][k];
        b = A[dr-(1<<k)+1][k];
        if (niv[a] < niv[b])
            fout << nod[a] << '\n';
        else fout << nod[b] << '\n';
    }
    return 0;
}

void DFS(int x)
{
    int i;

    uz[x] = 1;
    nod[++nr] = x;
    if (!poz[x])
        poz[x] = nr;
    niv[nr] = nivel;
    for (i=0;i<L[x].size();i++)
        if (!uz[L[x][i]])
        {
            nivel++;
            DFS(L[x][i]);
            nivel--;
            nod[++nr] = x;
            niv[nr] = nivel;
        }
}

void rmq()
{
    int i, j, k;

    for (k=0;(1<<(k+1))<=nr;k++);
    for (i=1;i<=nr;i++)
        A[i][0] = i;
    for (j=1;j<=k;j++)
        for (i=1;i<=nr;i++)
        {
            int a = A[i][j-1];
            int b = A[i+(1<<(j-1))][j-1];
            if (niv[a] < niv[b])
                A[i][j] = a;
            else A[i][j] = b;
        }
}