Cod sursa(job #1078139)

Utilizator Iustin_BulimarFMI Iustin Bulimar Iustin_Bulimar Data 12 ianuarie 2014 01:27:37
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");

const int n_max=100002;
const int log_n_max=18;

int n, m, i, x, y, k, level[n_max], e[2*n_max+4], apear[n_max], rm[log_n_max][n_max];
vector<int> a[n_max];

void mark(int nod)
{
    e[++k]=nod;
    apear[nod]=k;
}

void dfs(int nod)
{
    int i;
    mark(nod);
    for(i=0; i<a[nod].size(); i++)
        {
            dfs(a[nod][i]);
            mark(nod);
        }
}

void RMQ()
{
    int i, j;
    for(j=1; j<=k; j++)
        rm[0][j]=j;
    for(i=1; (1<<i)<=k; i++)
        for(j=1; j+(1<<i)-1<=k; j++)
            if(level[e[rm[i-1][j]]] <= level[e[rm[i-1][j+(1<<(i-1))]]])
                rm[i][j]=rm[i-1][j];
            else
                rm[i][j]=rm[i-1][j+(1<<(i-1))];
}

int LCA(int x, int y)
{
    int k;
    if(x>y) swap(x, y);
    k=log2(y-x+1);
    if(level[e[rm[k][x]]] < level[e[rm[k][y-(1<<k)+1]]])
        return rm[k][x];
    return rm[k][y-(1<<k)+1];
}

int main()
{
    cin>>n>>m;
    for(i=2; i<=n; i++)
    {
        cin>>x;
        a[x].push_back(i);
        level[i]=level[x]+1;
    }
    dfs(1);
    RMQ();
    while(m--)
    {
        cin>>x>>y;
        cout<<e[LCA(apear[x], apear[y])]<<'\n';
    }
    return 0;
}