Cod sursa(job #733319)

Utilizator tzipleatudTudor Tiplea tzipleatud Data 11 aprilie 2012 20:20:13
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.27 kb
#include <fstream>
#include <vector>
#define N 100010

using namespace std;

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

vector<int> A[N];

int n,m,i,j,k,E[2*N],First[N],Lev[2*N],lg[2*N],a,b;
int rmq[21][4*N];

void DF(int nod,int lvl) {
    ++k;
    E[k]=nod;
    Lev[k]=lvl;
    First[nod]=k;
    for (int i=0;i<A[nod].size();i++) {
        DF(A[nod][i],lvl+1);
        ++k;
        E[k]=nod;
        Lev[k]=lvl;
    }
}

void RMQ() {
    int l;
    for (i=1;i<=k;i++) rmq[0][i]=i;
    for (i=2;i<=k;i++) lg[i]=lg[i/2]+1;
    for (i=1;(1<<i)<k;i++)
        for (j=1;j<=k-(1<<i);j++) {
            l=1<<(i-1);
            rmq[i][j]=rmq[i-1][j];
            if (Lev[rmq[i-1][j]]>Lev[rmq[i-1][j+l]])
                rmq[i][j]=rmq[i-1][j+l];
        }
    return;
}

int solve(int a,int b) {
    a=First[a];b=First[b];
    if (a>b) swap(a,b);
    int l=lg[b-a+1],sh=b-a+1-(1<<l);
    int ANS=rmq[l][a];
    if (Lev[ANS]>Lev[rmq[l][a+sh]]) ANS=rmq[l][a+sh];
    return E[ANS];
}

int main() {
    f >> n >> m;
    for (i=2;i<=n;i++) {
        f >> j;
        A[j].push_back(i);
    }
    DF(1,0);
    RMQ();
    for (i=1;i<=m;i++) {
        f >> a >> b;
        g << solve(a,b) << '\n';
    }
    f.close();g.close();
    return 0;
}