Cod sursa(job #377109)

Utilizator vladiiIonescu Vlad vladii Data 23 decembrie 2009 15:04:48
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.76 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;

vector<int> G[100001];
int H[100001], poz[100001], k, rmq[20][100001], L[100001];

void DFS(int nod, int lev) {
    //parcurgere Euler
    //nodurile sunt stocate in H[ ] si prima pozitia pe care apar ele in poz[ ]
    H[++k]=nod;
    L[k]=lev;
    poz[nod]=k;
    for(vector<int>::iterator it=G[nod].begin(); it!=G[nod].end(); it++) {
         DFS(*it, lev+1);
         H[++k]=nod;
         L[k]=lev;
    }
}

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

int main() {
    fstream f1, f2;
    int n, m, i, j, p, q, x, y, aux;
    int lg[200002], sol;
    f1.open("lca.in", ios::in);
    f1>>n>>m;
    for(i=2; i<=n; i++) {
         f1>>p;
         G[p].push_back(i);
    }
    DFS(1, 0);
    lg[1]=0;
    for(i=2; i<=k; i++) {
         lg[i]=lg[i >> 1] + 1;
    }
    for(i=1; i<=k; i++) {
         rmq[0][i]=i;
    }
    for(i=1; (1<<i)<k; i++) {
         for(j=1; j<=k-(1 << i)+1; j++) {
              int l = 1 << (i - 1);
              rmq[i][j]=rmq[i-1][j];
              if(L[rmq[i-1][j+l]]<L[rmq[i][j]]) {
                   rmq[i][j] = rmq[i-1][j+l];
              }
         }
    }
    f2.open("lca.out", ios::out);
    for(i=1; i<=m; i++) {
         f1>>p>>q;
         //returneaza minimul secventei dintre poz[p], poz[q];
         p=poz[p]; q=poz[q];
         if(p>q) { swap(p, q); }
         //(int)(floor(log2((double)(n))));
         x=lg[q-p+1];
         aux=q-p+1-(1 << x);
         //rmq[x][p], rmq[x][p+aux]
         sol=rmq[x][p];
         if(L[sol]>L[rmq[x][p+aux]]) {
              sol=rmq[x][p+aux];
         }
         f2<<H[sol]<<endl;
    }
    f1.close(); f2.close();
    return 0;
}