Cod sursa(job #1687782)

Utilizator superstar1998Moldoveanu Vlad superstar1998 Data 13 aprilie 2016 08:30:10
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.51 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
#include <algorithm>
#define pb push_back
#define mp make_pair
#define MAXN 100010
#define MAXL 20
#define INFILE "lca.in"
#define OUTFILE "lca.out"
using namespace std;
ifstream f(INFILE);
ofstream g(OUTFILE);
int n,m,k;
vector<int> G[MAXN];
int L[MAXN<<1],H[MAXN],first[MAXN],lg[MAXN<<1];
int rmq[MAXL][MAXN<<2];
void df(int nod, int nv)
{
    H[++k]=nod;
    L[k]=nv;
    first[nod]=k;
    for(vector<int>::iterator it=G[nod].begin();it!=G[nod].end();it++)
    {
        df(*it,nv+1);
        H[++k]=nod;
        L[k]=nv;
    }
}
void Rmq()
{
    for(int i=2;i<=k;i++)
        lg[i]=lg[i>>1]+1;
    for(int i=1;i<=k;i++)
        rmq[0][i]=i;
    for(int i=1;(1<<i)<k;i++)
        for(int j=1;j<=k-(1<<i);j++)
        {
            int l=1<<(i-1);
            rmq[i][j]=rmq[i-1][j];
            if(L[rmq[i-1][j+l]]<L[rmq[i][j]])
                rmq[i][j]=rmq[i-1][j+l];
        }
}
int lca(int x, int y)
{
    int diff,l,sol,sh;
    int a=first[x],b=first[y];
    if(a>b)swap(a,b);
    diff=b-a+1;
    l=lg[diff];
    sol=rmq[l][a];
    sh=diff-(1<<l);
    if(L[sol]>L[rmq[l][a+sh]])
        sol=rmq[l][a+sh];
    return H[sol];
}
int main()
{
    int x,y;
    f>>n>>m;
    for(int i=2;i<=n;i++)
    {
        f>>x;
        G[x].pb(i);
    }
    df(1,0);
    Rmq();
    for(int i=1;i<=m;i++)
    {
        f>>x>>y;
        g<<lca(x,y)<<"\n";
    }
    f.close();
    g.close();
    return 0;
}