Cod sursa(job #1443373)

Utilizator emanuel_rRamneantu Emanuel emanuel_r Data 27 mai 2015 20:18:36
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.65 kb
#include <fstream>
#include <vector>
#define NMax 100005
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

vector <int> G[NMax];
int Euler[2*NMax],First[NMax], Level[2*NMax],Log[2*NMax],RMQ[20][2*NMax];
int N,M,K;

void DFS(int Nod,int level)
{
    Euler[++K] = Nod;
    Level[K] = level;
    First[Nod] = K;


    for(int i = 0; i < (int) G[Nod].size(); ++i)
        {
            int Vecin = G[Nod][i];

            DFS(Vecin,level + 1);
            Euler[++K] = Nod;
            Level[K] = level;
        }
}

void Read()
{
    fin>>N>>M;
    for(int i = 2; i<=N; i++)
        {
            int x;
            fin>>x;
            G[x].push_back(i);
        }
}

void Precalculate()
{

    for(int i = 2; i <= K; ++i)
        Log[i] = Log[i/2] + 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 <= K - (1<<i); ++j )
            {
                int Power = (1<<(i-1));

                RMQ[i][j] = RMQ [i-1][j];

                if(Level[RMQ[i-1][j + Power]]< Level[RMQ[i][j]])
                    RMQ[i][j] = RMQ [i-1][j + Power];
            }
}

int LCA(int x, int y)
{
    x = First[x];
    y = First[y];
    if(x>y)
        swap(x,y);
    int Dif = Log[y-x+1];
    int Sol = RMQ[Dif][x];
    if(Level[RMQ[Dif][y-(1<<Dif) + 1]]<Sol)
        Sol = RMQ[Dif][y-(1<<Dif) + 1];

    return Euler[Sol];

}

void Solve()
{
    while(M--)
    {
        int x,y;
        fin>>x>>y;
        fout<<LCA(x,y)<<"\n";
    }
}

int main()
{
    Read();
    DFS(1,0);
    Precalculate();
    Solve();
    return 0;
}