Cod sursa(job #1363778)

Utilizator Athena99Anghel Anca Athena99 Data 27 februarie 2015 11:11:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.58 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int nmax= 100000;
const int lmax= 20;

bool u[nmax+1];

int k;
int l[2*nmax+1], e[2*nmax+1], lvl[nmax+1], ind[nmax+1], d[2*nmax+1][lmax+1];

vector <int> g[nmax+1];

void dfs( int x ) {
    u[x]= 1;
    e[++k]= x;
    for ( vector <int>::iterator it= g[x].begin(); it!=g[x].end(); ++it ) {
        if ( u[*it]==0 ) {
            lvl[*it]= lvl[x]+1;
            dfs(*it);
            e[++k]= x;
        }
    }
}

int query( int a, int b ) {
    int x= min(ind[a], ind[b]), y= max(ind[a], ind[b]), k= 0, ans= 0;
    for ( int p= 1; 2*p<=y-x+1; p*= 2, ++k ) ;

    if ( l[d[x][k]]<l[d[y-(1<<k)+1][k]] ) {
        ans= d[x][k];
    } else {
        ans= d[y-(1<<k)+1][k];
    }

    return ans;
}

int main(  ) {
    int n, m;
    fin>>n>>m;
    for ( int i= 1; i<=n-1; ++i ) {
        int x;
        fin>>x;

        g[x].push_back(i+1);
    }

    dfs(1);
    for ( int i= 1; i<=k; ++i ) {
        l[i]= lvl[e[i]];
        if ( ind[e[i]]==0 ) ind[e[i]]= i;
    }

    for ( int i= 1; i<=k; ++i ) d[i][0]= i;
    for ( int j= 1; (1<<j)<=k; ++j ) {
        for ( int i= 1; i+(1<<j)-1<=k; ++i ) {
            if ( l[d[i][j-1]]<l[d[i+(1<<(j-1))][j-1]] ) {
                d[i][j]= d[i][j-1];
            } else {
                d[i][j]= d[i+(1<<(j-1))][j-1];
            }
        }
    }

    for ( int i= 1; i<=m; ++i ) {
        int x, y;
        fin>>x>>y;

        fout<<e[query(x, y)]<<"\n";
    }


    return 0;
}