Cod sursa(job #1295866)

Utilizator danalex97Dan H Alexandru danalex97 Data 20 decembrie 2014 12:44:24
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

#define OFFLINE

#define F cin
#define G cout

const int N = 100010;

int n,m,first[N],euler[N<<2],aint[N<<4],l;
vector<int> v[N];

void build(int n,int l,int r)
{
    if ( l == r )
    {
        aint[n] = euler[l];
        return;
    }
    int m = (l + r) / 2;

    build(n*2,l,m);
    build(n*2+1,m+1,r);

    aint[n] = min(aint[n*2],aint[n*2+1]);
}

int ask(int n,int l,int r,int il,int ir)
{
    if ( il > r || ir < l ) return 1<<30;
    if ( il <= l && r <= ir ) return aint[n];

    int m = (l + r) / 2;
    int qa = ask(n*2,l,m,il,ir);
    int qb = ask(n*2+1,m+1,r,il,ir);

    return min(qa,qb);
}

int lca(int x,int y)
{
    int lt = first[x];
    int rt = first[y];
    if ( lt > rt ) swap(lt,rt);
    return ask(1,1,l,lt,rt);
}

void parc(int x,int d)
{
    euler[++l] = x;
    first[x] = l;
    for (int i=0;i<int(v[x].size());++i)
    {
        int y = v[x][i];
        if ( y != d )
        {
            parc(y,x);
            euler[++l] = x;
        }
    }
}

int main()
{
    ios::sync_with_stdio(0);
    #ifdef OFFLINE
        ifstream F("lca.in");
        ofstream G("lca.out");
    #endif

    F>>n>>m;
    for (int i=2,x,y;i<=n;++i)
    {
        x = i;
        F>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    parc(1,0);
    build(1,1,l);
    for (int i=1,x,y;i<=m;++i)
    {
        F>>x>>y;
        G<<lca(x,y)<<'\n';
    }
}