Cod sursa(job #1088460)

Utilizator harababurelPuscas Sergiu harababurel Data 20 ianuarie 2014 15:49:21
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.33 kb
#include <iostream>
#include <fstream>
#include <vector>
#define nmax 100005
#define mmax 2000005
#define logmax 20
#define inf (1<<30)
using namespace std;

vector <int> v[nmax];
int Euler[2*nmax], level[2*nmax], M[2*nmax][logmax], first[nmax];
int n, m, x, y;

void explore(int curr, int h) {
    Euler[++Euler[0]] = curr;
    level[++level[0]] = h;

    if(first[curr] == 0) first[curr] = Euler[0];

    if(v[curr].size() == 0) return;
    for(int i=0; i<v[curr].size(); i++) {
        explore(v[curr][i], h+1);
        Euler[++Euler[0]] = curr;
        level[++level[0]] = h;
    }
}

int RMQ(int i, int j) {
    int k = 0;
    while(1<<(k+1)<=j-i+1) k++;
    return (level[M[i][k]] < level[M[j-(1<<k)+1][k]]? Euler[M[i][k]] : Euler[M[j-(1<<k)+1][k]]);
}

int main() {
    ifstream f("lca.in");
    ofstream g("lca.out");

    f>>n>>m;
    for(int i=2; i<=n; i++) {
        f>>x;
        v[x].push_back(i);
    }
    explore(1, 1);

    for(int i=1; i<=Euler[0]; i++) M[i][0] = i;
    level[0] = inf;

    for(int j=1; (1<<j)<=Euler[0]; j++)
        for(int i=1; i<=Euler[0]; i++)
            M[i][j] = level[ M[i][j-1] ] < level [ M[i+(1<<(j-1))][j-1] ]? M[i][j-1] : M[i+(1<<(j-1))][j-1];

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

    return 0;
}