Cod sursa(job #1953618)

Utilizator nicu_serteSerte Nicu nicu_serte Data 4 aprilie 2017 21:57:54
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.59 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
#define nmax 100005
vector <int> g[nmax], eul, niv, rmq[18], lg;
int n, m, first[nmax], k;
void citire()
{
    int i, x;
    fin>>n>>m;
    for(i=2; i<=n; i++)
    {
        fin>>x;
        g[x].push_back(i);
    }
}
void dfs(int nod, int level)
{
    vector<int>::iterator it;
    eul.push_back(nod);
    niv.push_back(level);
    first[nod]=eul.size()-1;
    for(it=g[nod].begin(); it!=g[nod].end(); it++)
    {
        dfs(*it, level+1);
        eul.push_back(nod);
        niv.push_back(level);
    }
}
void preprocesareRMQ()
{
    int i, j, l;
    k=niv.size();
    for(i=0; i<=17; i++)
        rmq[i].resize(niv.size()+5, 0);
    for(i=1; i<=k; i++)
        rmq[0][i]=i;
    lg.resize(niv.size()+5, 0);
    for(i=2; i<=k; i++)
        lg[i]=1+lg[i>>1];
    for(i=1; (1<<i)<k; i++)
        for(j=1; j+(1<<i)<=k; j++)
        {
            l=1<<(i-1);
            rmq[i][j]=rmq[i-1][j];
            if(niv[rmq[i-1][j+l]]<niv[rmq[i][j]])
                rmq[i][j]=rmq[i-1][j+l];
        }
}
int lca(int x, int y)
{
    int st, dr, dif, l;
    st=first[x]; dr=first[y];
    if(st>dr)
        swap(st, dr);
    dif=dr-st+1;
    l=lg[dif];
    if(niv[rmq[l][st]]<niv[rmq[l][st+dif-(1<<l)]])
        return eul[rmq[l][st]];
    return eul[rmq[l][st+dif-(1<<l)]];
}
int main()
{
    int x, y;
    citire();
    dfs(1, 0);
    preprocesareRMQ();
    while(m)
    {
        m--;
        fin>>x>>y;
        fout<<lca(x, y)<<'\n';
    }
    return 0;
}