Cod sursa(job #1535101)

Utilizator refugiatBoni Daniel Stefan refugiat Data 24 noiembrie 2015 12:42:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.42 kb
#include<iostream>
#include<fstream>
#include<algorithm>
#include<vector>
using namespace std;
//FILE* si=fopen("siruri2.in","r");
ifstream si("lca.in");
ofstream so("lca.out");
const int NMAX=200005;
int k;
vector<int> v[NMAX];
int eu [2*NMAX],niv[2*NMAX],pa[NMAX],l[NMAX];
int sol[20][4*NMAX];
void dfs(int nod,int n)
{
    eu[++k]=nod;
    niv[k]=n;
    pa[nod]=k;
    vector<int>::iterator i;
    for(i=v[nod].begin();i!=v[nod].end();++i)
    {
        dfs(*i,n+1);
        eu[++k]=nod;
        niv[k]=n;
    }
}
int main()
{
    int n,m;
    int i;
    si>>n>>m;
    int a;
    for(i=2;i<=n;++i)
    {
        si>>a;
        v[a].push_back(i);
    }
    dfs(1,0);
    for(i=2;i<=k;++i)
        l[i]=l[i>>1]+1;
    for(i=1;i<=k;++i)
        sol[0][i]=i;
    int b,j;
    for(i=1,a=2;a<=k;++i,a<<=1)
    {
        b=k-a+1;
        for(j=1;j<=b;++j)
        {
            if(niv[sol[i-1][j]]<niv[sol[i-1][j+(a>>1)]])
                sol[i][j]=sol[i-1][j];
            else
                sol[i][j]=sol[i-1][j+(a>>1)];
        }
    }
    int x,val;
    for(i=0;i<m;++i)
    {
        si>>a>>b;
        a=pa[a];
        b=pa[b];
        if(a>b)
            swap(a,b);
        x=l[b-a+1];
        if(niv[sol[x][a]]<niv[sol[x][b-(1<<x)+1]])
            val=sol[x][a];
        else
            val=sol[x][b-(1<<x)+1];
        so<<eu[val]<<'\n';
    }
    so.close();
    return 0;
}