Cod sursa(job #1842135)

Utilizator roxanastRoxana Stiuca roxanast Data 6 ianuarie 2017 15:47:32
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <fstream>
#include <vector>
#define NMAX 100000
#define LMAX 20
using namespace std;

vector <int> g[NMAX+5];
//vector <int> ::iterator it;
int k,n,m;
int l[NMAX<<1],h[NMAX<<1],lg[NMAX<<1],first[NMAX],rmq[LMAX][NMAX<<2];


ifstream f("lca.in");
ofstream out("lca.out");
void dfs(int nod,int lvl){
    h[++k]=nod;
    l[k]=lvl;
    first[nod]=k;
    for(typeof (g[nod]).begin() it=(g[nod]).begin();it!=(g[nod]).end();++it){
        dfs(*it,lvl+1);
        h[++k]=nod;
        l[k]=lvl;
    }
}
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;(i<<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()
{
    f>>n>>m;
    for(int i=2;i<=n;i++){
        int x;
        f>>x;
        g[x].push_back(i);
    }

    dfs(1,0);
    RMQ();
    for(int i=1;i<=m;i++){
        int x,y,LCA;
        f>>x>>y;
        LCA=lca(x,y);
        if(LCA==0)
            out<<1<<'\n';
        else
            out<<LCA<<'\n';
    }
    return 0;
}