Cod sursa(job #1392763)

Utilizator bogdanboboc97Bogdan Boboc bogdanboboc97 Data 18 martie 2015 21:18:19
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.38 kb
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
vector< vector<int> > a;
vector<int> h,lvl,pos,lg;
int rmq[20][400002],k,n,m;
//....................
void df(int x,int level)
{
    h[++k]=x;
    lvl[k]=level;
    pos[x]=k;
    for(auto i: a[x])
    {
        df(i,level+1);
        h[++k]=x;
        lvl[k]=level;
    }
}
//......................
void RMQ()
{
    for(int i=1;i<=k;i++)
    {
        if(i>=2)lg[i]=lg[i/2]+1;
        rmq[0][i]=i;
    }
    for(int i=1;(1<<i)<=k;i++)
    {
        int pp=1<<(i-1);
        for(int j=1;j+(1<<i)-1<=k;j++)
            if(lvl[ rmq[i-1][j] ] > lvl[ rmq[i-1][j+pp] ])rmq[i][j]=rmq[i-1][j+pp];
            else rmq[i][j]=rmq[i-1][j];
    }
}
//.....................
int lca(int xx,int yy)
{
    int x=pos[xx],y=pos[yy];
    if(x>y)swap(x,y);
    int diff=lg[y-x+1];
    int sol;
    if(lvl[ rmq[diff][y-(1<<diff)+1] ] < lvl[ rmq[diff][x] ])sol=rmq[diff][y-(1<<diff)+1];
    else sol=rmq[diff][x];
    return h[sol];
}
int main()
{
    in>>n>>m;
    a=vector< vector<int> > (n+1);
    h=lvl=lg=vector<int> (2*n+1);
    pos=vector<int> (n+1);
    for(int i=2;i<=n;i++)
    {
        int x;
        in>>x;
        a[x].pb(i);
    }
    //................
    df(1,0);
    RMQ();
    //................
    for(;m;m--)
    {
        int x,y;
        in>>x>>y;
        out<<lca(x,y)<<'\n';
    }
    return 0;
}