Cod sursa(job #1944070)

Utilizator andrei.sasaAndrei SaSa andrei.sasa Data 28 martie 2017 22:25:01
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <iostream>
#include <vector>
#include <fstream>

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

vector <int> G[100005];
int n,m,k,first[100005],stk[100005 << 1],nivel[100005 << 1], lg[100005 << 1], rmq[25][100005 << 1];

void parc_euler(int x, int level)
{
    stk[++k]=x;
    nivel[k]=level;
    first[x]=k;
    for(int i=0;i<G[x].size();i++)
        {
            parc_euler(G[x][i],level+1);
            nivel[++k]=level;
            stk[k]=x;
        }
}

int lca(int x, int y)
{
    x=first[x];
    y=first[y];
    if(x>y) swap(x,y);
    int l=lg[y-x+1];
    int minim = rmq[l][x];
    if(nivel[minim] > nivel[rmq[l][y- (1 << l)+1]]);
        minim=rmq[l][y- (1 << l)+1];
    return stk[minim];
}

int main()
{
    f>>n>>m;
    for(int i=2;i<=n;i++)
        {
            int x;
            f>>x;
            G[x].push_back(i);
        }
    parc_euler(1,0);
    /*for(int i=1;i<=k;i++)
        cout<<stk[i]<<' ';
    cout<<'\n';
    for(int i=1;i<=k;i++)
        cout<<nivel[i]<<' ';*/
    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;(1 << i)<=k;i++)
        for(int j=1; j + (1 << i) -1 <=k;j++)
    {
        rmq[i][j]=rmq[i-1][j];
        int nr= 1 << (i-1);
        if(nivel[rmq[i][j]] > nivel[rmq[i-1][j+ nr]])
            rmq[i][j]=rmq[i-1][j+ nr];
    }
    for(int i=1;i<=m;i++)
    {
        int a,b;
        f>>a>>b;
        g<<lca(a,b)<<'\n';
    }
    f.close();
    g.close();



    return 0;
}