Cod sursa(job #377101)

Utilizator vladiiIonescu Vlad vladii Data 23 decembrie 2009 14:46:24
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.48 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;

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

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

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];
    f1.open("lca.in", ios::in);
    f1>>n>>m;
    for(i=2; i<=n; i++) {
         f1>>p;
         G[p].push_back(i);
    }
    DFS(1);
    for(i=2; i<=k; i++) {
         lg[i]=lg[i >> 1] + 1;
    }
    for(i=1; i<=k; i++) {
         rmq[0][i]=H[i];
    }
    for(i=1; i<lg[k]; i++) {
         for(j=1; j<=k-(1 << i)+1; j++) {
              rmq[i][j]=min(rmq[i-1][j], rmq[i-1][j + (int)pow(2, i-1)]);
         }
    }
    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]
         f2<<min(rmq[x][p], rmq[x][p+aux])<<endl;
    }
    f1.close(); f2.close();
    return 0;
}