Cod sursa(job #1347970)

Utilizator Pintilie_AndreiFII-Pintilie Andrei Pintilie_Andrei Data 19 februarie 2015 13:29:38
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.13 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define oo 2000000000
#define N 100005
using namespace std;
queue <int> q;
vector <int> a[N];
int ad[N],rmq[20][N],lg[N],eu[3*N],v[N],poz[N];
int n,m,top;
void Ini()
{
    for(int i=1; i<=n; i++)
    ad[i]=oo;
}
void BFS()
{
    q.push(1);
    ad[1]=0;
    int nod,k,i;
    while(!q.empty())
    {
        k=q.front();
        q.pop();
        for(i=0; i<a[k].size(); i++)
        {

            nod=a[k][i];

            if(ad[nod]>ad[k]+1)
            {
                ad[nod]=ad[k]+1;
                //cout<<nod<<" "<<ad[nod]<<"\n";
                q.push(nod);
            }
        }
    }
}
void Lungime()
{
    for(int i=2; i<=n; i++)
    lg[i]=lg[i>>1]+1;
}
void Create_Rmq()
{
    int i,j,k;
    for(i=1; i<=top; i++)
    rmq[0][i]=eu[i];

    for(i=1; (1<<i)<=top; i++)
    {
        k=1<<(i-1);
        for(j=1<<i; j<=top; j++)
        rmq[i][j]=min(rmq[i-1][j],rmq[i-1][j-k]);
    }
}
void Euler(int k)
{
    int i;
    v[k]=1;
    eu[++top]=k;
    for(int i=0; i<a[k].size(); i++)
    if(!v[a[k][i]])
    {
    Euler(a[k][i]);
    eu[++top]=k;
    }


}
int Pozitiaeu()
{
    int i;
    for(i=1; i<=top; i++)
    v[i]=0;
    for(i=1; i<=top; i++)
    if(!v[i]) { poz[eu[i]]=i; v[i]=1; }
}
int LCA(int x, int y)
{
    int d,sol;
    d=lg[y-x+1];
    sol=min(rmq[d][x+(1<<d)-1],rmq[d][y]);
    return sol;

}
int main()
{
    ifstream fin("lca.in");
    fin>>n>>m;
    int i,x,d,sol,y;
    for(i=2; i<=n; i++ )
    {
        fin>>x;
        a[x].push_back(i);
    }
    //Ini();
    //BFS();
    Euler(1);
    Pozitiaeu();
    Lungime();
    Create_Rmq();
//        for(i=1; i<=top; i++)
//    cout<<eu[i]<<" ";
//    cout<<"\n";

    ofstream fout("lca.out");
    for(i=1; i<=m; i++)
    {
        fin>>x>>y;
       // cout<<poz[x]<<" "<<poz[y]<<"\n";
        if(poz[x]>poz[y]) fout<<LCA(poz[y],poz[x])<<"\n";
        else fout<<LCA(poz[x],poz[y])<<"\n";

        //sol=min(ad[rmq[d][x+(1<<d)-1]],ad[rmq[d][y-(1<<d)+i]]);
        //cout<<sol<<"\n";
    }
    return 0;
}