Cod sursa(job #2155037)

Utilizator DavidLDavid Lauran DavidL Data 7 martie 2018 15:46:00
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.99 kb
#include <fstream>
#include <vector>
#define MAX 100005
#define LOG 25
using namespace std;
ifstream fi("lca.in");
ofstream fo("lca.out");

vector <int> G[MAX];
vector <int> euler;
vector <int> eulerNivel;
int P[MAX],nivel[MAX];
int prima[MAX];
pair <int,int> minim[LOG][MAX];
int n,m;


void dfs(int nod)
{
    euler.push_back(nod);
    //eulerNivel.push_back(nivel[nod]);
    prima[nod]=euler.size()-1;
    for (auto v: G[nod])
    {
        nivel[v]=nivel[nod]+1;
        dfs(v);
        euler.push_back(nod);
    }
}

void getRMQ()
{
    /// lucram pe nivelurile din euler
    for (int i=0; i<euler.size(); i++)
        minim[0][i]={nivel[euler[i]],euler[i]};

    for (int b=1; (1<<b)<euler.size(); b++)
    {
        for (int i=0; i<euler.size(); i++)
        {
            if (minim[b-1][i].first<minim[b-1][(i+(1<<(b-1)))].first)
                minim[b][i].second=minim[b-1][i].second;
            else
                minim[b][i].second=minim[b-1][(i+(1<<(b-1)))].second;

            minim[b][i].first=min(minim[b-1][i].first,
                                  minim[b-1][(i+(1<<(b-1)))].first);

        }
    }
}

int valMin(int a,int b)
{
    /// pozitia pe care se afla minimul in [a,b]
    if (a==b)
        return a;

    //int l=b-a+1;
    int p=0;
    while (a+(1<<p)<=b)
        p++;
    p--;

    ///int rez=min(minim[p][a],minim[p][b-(1<<p)]);

    if (minim[p][a].first<minim[p][b-(1<<p)].first)
        return minim[p][a].second;
    return minim[p][b-(1<<p)].second;
}

int main()
{
    fi>>n>>m;
    for (int i=2; i<=n; i++)
        fi>>P[i],G[P[i]].push_back(i);

    dfs(1);

    //for (auto x: euler)
        //fo<<nivel[x]<<" ";

    getRMQ();

    while (m--)
    {
        int a,b;
        fi>>a>>b;
        if (a==b)
        {
            fo<<a<<"\n";
            continue;
        }
        if (prima[a]>prima[b])
            swap(a,b);
        fo<<valMin(prima[a],prima[b])<<"\n";
    }

    return 0;
}