Cod sursa(job #1347991)

Utilizator Pintilie_AndreiFII-Pintilie Andrei Pintilie_Andrei Data 19 februarie 2015 13:45:00
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 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];
struct str
{
    int nod,niv;
};
str eu[2*N];
int rmq[20][2*N],lg[2*N],v[2*N],poz[2*N];
int n,m,top;
void Lungime()
{
    for(int i=2; i<=n; i++)
    lg[i]=lg[i>>1]+1;
}
void Create_Rmq()
{
    int i,j,k,p1,p2;
    for(i=1; i<=top; i++)
    rmq[0][i]=i;

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


}
int LCA(int x, int y)
{
    int d,sol,p1,p2;
    d=lg[y-x+1];
    p1=rmq[d][x+(1<<d)-1];
    p2=rmq[d][y];
    if(eu[p1].niv < eu[p1].niv)
    sol=p1;
    else sol=p2;
    return eu[sol].nod;

}
void Pozitiaeu()
{
    int i;
    for(i=1; i<=top; i++)
    v[i]=0;
    for(i=1; i<=top; i++)
    if(!v[eu[i].nod])
    {
        poz[eu[i].nod]=i;
        v[eu[i].nod]=1;
    }
}
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,0);
    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;
}