Cod sursa(job #2345490)

Utilizator Anastasia11Susciuc Anastasia Anastasia11 Data 16 februarie 2019 13:33:01
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.49 kb
#include <iostream>
#include <fstream>
#include <vector>
#define Nmax 100005

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

int n, m;
vector <int> v[Nmax];
int first[Nmax], eul[2*Nmax], ne;
int rmq[19][2*Nmax], niv[Nmax], log2[Nmax];

void dfs(int x)
{
    ne++;
    eul[ne]=x;
    first[x]=ne;
    for (int i = 0, l=v[x].size(); i < l; i++)
    {
        int y=v[x][i];
        niv[y]=niv[x]+1;
        dfs(y);
        eul[++ne]=x;
    }
}

void RMQ()
{
    for (int i = 2; i <= n; i++)
        log2[i]=log2[i/2]+1;

    for (int i = 1; i <= ne; i++) rmq[0][i]=eul[i];

    for (int i = 1; (1<<i) <= ne; i++)
        for (int j = 1; j+(1<<i)-1 <= ne; j++)
        {
            int a=rmq[i-1][j];
            int b=rmq[i-1][j+(1<<(i-1))];
            if(niv[a]<niv[b]) rmq[i][j]=a;
            else rmq[i][j]=b;
        }

}

int query(int x, int y)
{
    int a=first[x], b=first[y];
    if(a>b) swap(a, b);
    int diff=b-a+1;
    int aa=rmq[log2[diff]][a];
    int bb=rmq[log2[diff]][b-(1<<(log2[diff]))+1];

    if (niv[aa] < niv[bb])
        return aa;
    else return bb;
}

int main()
{
    f >> n >> m;
    for (int i = 2, x; i <= n; i++)
    {
        f >> x;
        v[x].push_back(i);
    }
    dfs(1);
    RMQ();
    int x, y;
    while(m--)
    {
        f >> x >> y;
        g << query(x, y) << '\n';
    }
    //cout << ne << '\n';
    //for (int i = 1; i <= ne; i++) cout << eul[i] << " ";
    return 0;
}