Cod sursa(job #1833770)

Utilizator rares96cheseliRares Cheseli rares96cheseli Data 23 decembrie 2016 06:24:34
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.32 kb
#include <bits/stdc++.h>
using namespace std;

#define NMAX 100005
#define k_NMAX 17

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

int N, M, x, rmq[k_NMAX + 1][2 * NMAX], _first[NMAX], lg[2 * NMAX], euler[2 * NMAX], level[NMAX], y;
vector < int > G[NMAX];

void dfs(int node, int currentLevel)
{
    level[node] = currentLevel;
    euler[++euler[0]] = node;
    _first[node] = euler[0];
    vector<int>::iterator it=G[node].begin();
    for (; it!=G[node].end(); ++it)
        dfs(*it, currentLevel + 1), euler[++euler[0]]=node;
}

int lca(int node1, int node2)
{
    int st=_first[node1], dr=_first[node2];
    if (st>dr) swap(st, dr);
    int k=lg[dr-st+1], x=rmq[k][st], y=rmq[k][dr-(1<<k)+1];
    if (level[x]<level[y]) return x;
        else return y;
}

int main()
{
    f>>N>>M;
    for (int i=2; i<=N; ++i)
        f>>x, G[x].push_back(i);

    dfs(1, 1);
    rmq[0][1]=euler[1];
    for (int i=2; i<=euler[0]; ++i)
        lg[i]=lg[i/2]+1, rmq[0][i]=euler[i];

    for (int i=1; (1<<i)<=euler[0]; ++i)
        for (int j=1; j<=euler[0]-(1<<i)+1; ++j)
        {
            x=rmq[i-1][j]; y=rmq[i-1][j+(1<<(i-1))];
            if (level[x]<level[y]) rmq[i][j]=x;
                else rmq[i][j]=y;
        }

    for (int i=1; i<=M; ++i)
        f>>x>>y, g<<lca(x, y)<<'\n';
    return 0;
}