Cod sursa(job #1380009)

Utilizator rares96cheseliRares Cheseli rares96cheseli Data 6 martie 2015 21:05:17
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.2 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");

int N, M, x, lg[200005], rmq[20][200005], Euler[200005], dim, First[200005], Lvl[100005], y;
vector < int > G[100005];

void dfs(int nod, int level)
{
    Euler[++dim]=nod; Lvl[nod]=dim; First[nod]=dim;
    vector<int>::iterator it=G[nod].begin();
    for (; it!=G[nod].end(); ++it)
        dfs(*it, level+1), Euler[++dim]=nod;
}

int lca(int x, int y)
{
    int st=First[x], dr=First[y];
    if (st>dr) swap(st, dr);

    int Log=lg[dr-st+1], n1=rmq[Log][st], n2=rmq[Log][dr-(1<<Log)+1];
    if (Lvl[n1]<Lvl[n2]) return n1;
    return n2;
}

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<=dim; ++i)
        rmq[0][i]=Euler[i], lg[i]=lg[i/2]+1;

    for (int i=1; (1<<i)<=dim; ++i)
        for (int j=1; j<=dim-(1<<i)+1; ++j)
        {
            int x=rmq[i-1][j], y=rmq[i-1][j+(1<<(i-1))];
            if (Lvl[x]<Lvl[y]) rmq[i][j]=x;
                else rmq[i][j]=y;
        }

    while (M--)
        f>>x>>y, g<<lca(x, y)<<'\n';
    return 0;
}