Cod sursa(job #1537919)

Utilizator Vele_GeorgeVele George Vele_George Data 28 noiembrie 2015 11:54:02
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
#include <iostream>
#include <fstream>
#include <vector>
#define nmax 100005
using namespace std;

vector<int> Gf[nmax];
int Euler[2*nmax], First[nmax], Level[2*nmax], RMQ[20][2*nmax], Log[2*nmax];
int n, m, x, y, cnt=0;

void DFS(int x, int l)
{
    Euler[++cnt] = x;
    First[x] = cnt;
    Level[x] = l;
    for(int i=0; i<Gf[x].size(); i++)
    {
        DFS(Gf[x][i], l+1);
        Euler[++cnt] = x;
    }
    return;
}
void Gen_Log()
{
    Log[1]=0;
    for(int i=2; i<=cnt; i++)
    {
        Log[i] = Log[i/2]+1;
    }
}
void Gen_RMQ()
{
    Gen_Log();
    for(int j=1; j<=cnt; j++)
    {
        RMQ[0][j] = Euler[j];
    }
    for(int i=1; (1<<i)<=cnt; i++)
    {
        for(int j=1; j+(1<<i)-1<=cnt; j++)
        {
            if (Level[RMQ[i-1][j]] < Level[RMQ[i-1][j+(1<<(i-1))]]){
                RMQ[i][j] = RMQ[i-1][j];   //stanga
            }else{
                 RMQ[i][j] = RMQ[i-1][j+(1<<(i-1))]; //dreapta
            }

        }
    }

    return;
}

int LCA(int x, int y)
{
    x = First[x];
    y = First[y];
    if (y < x) swap(x, y);
    int mn, k = Log[y - x + 1];

    if (Level[RMQ[k][x]] < Level[RMQ[k][y-(1<<k)+1]]){
        mn = RMQ[k][x];   //stanga
    }else{
        mn = RMQ[k][y-(1<<k)+1]; //dreapta
    }


    return mn;
}
int main()
{
    ifstream f("lca.in");
    ofstream g("lca.out");
    f >> n >> m;
    for(int i=2; i<=n; i++)
    {
        f >> x;
        Gf[x].push_back(i);
    }
    DFS(1,1);  //radacina si nivelu
    Gen_RMQ();

    for(int i=1; i<=m; i++)
    {
        f >> x >> y;
        g << LCA(x, y) << "\n";
    }

    f.close();
    g.close();
    return 0;
}