Cod sursa(job #1540201)

Utilizator Vele_GeorgeVele George Vele_George Data 2 decembrie 2015 13:27:48
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.82 kb
#include <iostream>
#include <fstream>
#include <vector>
#define nmax 100005
using namespace std;

vector<int> gf[nmax];
int RMQ[30][2*nmax], Euler[2*nmax], First[nmax], log[2*nmax], Level[nmax];
int cnt=0, n, m;

void dfs(int x)
{
    Euler[++cnt] = x;
    First[x] = cnt;

    for(int fiu=0; fiu<gf[x].size(); fiu++)
    {
        Level[gf[x][fiu]] = Level[x] +1;
        dfs(gf[x][fiu]);
        Euler[++cnt] = x;
    }
    return;
}

void gen_log()
{
    log[1] = 0;
    for(int i=2; i<=cnt; i++)
    {
        log[i] = log[i/2]+1;
    }
    return;
}

void gen_rmq()
{
    gen_log();
    for(int j=1; j<=cnt; j++)
    {
        RMQ[0][j] = Euler[j];
    }
    int k;
    for(int i=1; (1<<i)<=cnt; i++)
    {
        k = i-1;
        for(int j=1; j+(1<<i)-1<=cnt;j++)
        {
            if (Level[RMQ[k][j]] < Level[RMQ[k][j+(1<<k)]]){
                RMQ[i][j] = RMQ[k][j];             //stanga
            }else{
                RMQ[i][j] = RMQ[k][j+(1<<k)];    //dreapta
            }
        }
    }

    return;
}

int LCA(int x, int y)
{
    x = First[x];
    y = First[y];
    if (x > y) swap(x, y);
    int k = (y - x + 1);
        k = log[k];
    int mn;
    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;
    gf[0].push_back(1);
    int tata;

    for(int fiu=2; fiu<=n; fiu++)
    {
        f >> tata;
        gf[tata].push_back(fiu);
    }
    Level[1] = 1;

    dfs(1);
    gen_rmq();

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

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