Cod sursa(job #1807094)

Utilizator VictoriaNevTascau Victoria VictoriaNev Data 16 noiembrie 2016 00:25:16
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include <fstream>
#include <vector>

using namespace std;
const int NMAX=100005;
int nr_rmq;
int rmq[20][NMAX*2], first[NMAX], deep[NMAX];
vector<int> vertex[NMAX];

void dfs(int node)
{
    rmq[0][++nr_rmq]=node;
    first[node]=nr_rmq;
    for(int i=0; i<vertex[node].size(); i++)
    {
        int x=vertex[node][i];
        deep[x]=deep[node]+1;
        dfs(x);
        rmq[0][++nr_rmq]=node;
    }
}

int lca(int x, int y)
{
    x=first[x];
    y=first[y];
    if(x>y)
        swap(x, y);
    if(x==y)
        return x;
    int d=0;
    while((1<<d)<(y-x+1))
        d++;
    d--;
    if(deep[rmq[d][x]]<deep[rmq[d][y-(1<<d)+1]])
        return rmq[d][x];
    return rmq[d][y-(1<<d)+1];
}

void make_rmq()
{
    for(int l=1; (1<<l)<=nr_rmq; l++)
        for(int st=1; st+(1<<l)<=nr_rmq; st++)
        {
            int dr=st+(1<<(l-1));
            if(deep[rmq[l-1][st]]<deep[rmq[l-1][dr]])
                rmq[l][st]=rmq[l-1][st];
            else
                rmq[l][st]=rmq[l-1][dr];
        }
}

int main()
{
    ifstream in("lca.in");
    ofstream out("lca.out");
    int n, m;
    in>>n>>m;
    for(int i=2; i<=n; i++)
    {
        int x;
        in>>x;
        vertex[x].push_back(i);
    }
    dfs(1);
    make_rmq();
    while(m--)
    {
        int x, y;
        in>>x>>y;
        out<<lca(x, y)<<'\n';
    }
    return 0;
}