Cod sursa(job #1110787)

Utilizator oprea1si2si3Oprea Sebastian oprea1si2si3 Data 18 februarie 2014 13:19:54
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.57 kb
#include<fstream>
#include<iostream>
#include<vector>
using namespace std;

vector <pair<int,int> > euler;
vector <int> arbore[100100];
int N,M,Log[200200],rmq[18][200200],first[100100];

void dfs(int nod,int nivel) {

    int i,vecin;
    first[nod]=euler.size();
    euler.push_back(make_pair(nod,nivel));
    for(i=0;i<arbore[nod].size();i++){
        vecin=arbore[nod][i];
        dfs(vecin,nivel+1);
        euler.push_back(make_pair(nod,nivel));
    }

}

void initializare() {

    int i,j;
    euler.push_back(make_pair(0,0));
    dfs(1,0);
    N=N*2;
    for(i=2;i<=N;i++)
        Log[i]=Log[i/2]+1;
    for(i=1;i<=N;i++)
        rmq[0][i]=i;

    for(i=1;(1<<i)<=N;i++)
        for(j=1;j+(1<<i)-1<=N;j++)
            if(euler[rmq[i-1][j]].second<euler[rmq[i-1][j+(1<<(i-1))]].second)
                rmq[i][j]=rmq[i-1][j];
            else
                rmq[i][j]=rmq[i-1][j+(1<<(i-1))];

}

int lca(int x,int y) {

    x=first[x];
    y=first[y];
    if(x>y)
        swap(x,y);
    if(euler[rmq[Log[y-x+1]][x]].second< euler[rmq[Log[y-x+1]][y-(1<<Log[y-x+1])+1]].second)
        return  euler[rmq[Log[y-x+1]][x]].first;
    else
        return euler[rmq[Log[y-x+1]][y-(1<<Log[y-x+1])+1]].first;
}

int main() {

    ifstream in("lca.in");
    ofstream out("lca.out");
    int i,x,y;
    in>>N>>M;
    for(i=2;i<=N;i++) {
        in>>x;
        arbore[x].push_back(i);
    }
    initializare();
    for(i=1;i<=M;i++) {
        in>>x>>y;
        out<<lca(x,y)<<'\n';
    }
    in.close();
    out.close();
    return 0;

}