Cod sursa(job #1087058)

Utilizator marinMari n marin Data 18 ianuarie 2014 21:17:52
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.47 kb
#include <fstream>
#include <vector>
#define DIMN 100010
using namespace std;

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

vector<int> L[DIMN];
int E[2*DIMN];
int N[2*DIMN];
int F[DIMN];
int B[2*DIMN];
int D[20][2*DIMN];

int n, m, i, j, t, k, x, y, aux, len;

int minim(int a, int b) {
    if (a < b)
        return a;
    else
        return b;
}

void dfs(int nod, int niv) {
    E[++k] = nod;
    F[nod] = k;
    N[k] = niv;
    for (int i=0;i<L[nod].size(); i++) {
        dfs(L[nod][i], niv+1);
        E[++k] = nod;
        N[k] = niv;
    }
}


int main() {

    fin>>n>>m;
    for (i=2;i<=n;i++) {
        fin>>t;
        L[t].push_back(i);
    }

    dfs(1, 0);

    for (i=2;i<=2*n;i++)
        B[i] = B[i/2] + 1;

    for (j=1;j<=2*n;j++)
        D[0][j] = j;

    for (i=1;(1<<i) <= 2*n; i++) {
        for (j=1;j<=2*n;j++) {
            D[i][j] = D[i-1][j];
            if ( j+(1<<(i-1)) <= 2*n && N[D[i][j]] > N[D[i-1][j+(1<<(i-1))]]   )
                D[i][j] = D[i-1][j+(1<<(i-1))];
        }
    }

    while (m) {
        fin>>x>>y;
        x = F[x];
        y = F[y];
        if (x > y) {
            aux = x;
            x = y;
            y = aux;
        }

        len = B[  y - x + 1  ];

        if (N[D[len][x]] < N[D[len][y - (1<<len) + 1 ]])
            fout<<E[D[len][x]]<<"\n";
        else
            fout<<E[D[len][y - (1<<len) + 1 ]]<<"\n";

        m--;
    }

    return 0;
}