Cod sursa(job #929591)

Utilizator VisuianMihaiMihai Visuian VisuianMihai Data 27 martie 2013 09:39:42
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.38 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

vector<int>g[100001];
int euler[4*100001], niv[100001*4], first[100001];
int rmq[4*100001][20], lg[100001*4];
int n, m, x, nr, y;
void Euler(int x, int lvl)
{
    euler[++nr]=x;
    niv[nr]=lvl;
    first[x]=nr;
    for(vector<int>::iterator it=g[x].begin(); it<g[x].end(); it++ )
    {
        Euler(*it,lvl+1);
        euler[++nr]=x;
        niv[nr]=lvl;
    }
}

inline int Lca(int x, int y)
{
    x = first[x], y = first[y];
    if(x>y) swap(x,y);
    int l = lg[y-x+1];
    if(niv[rmq[x][l]] < niv[rmq[y-(1<<l)+1][l]])
        return euler[rmq[x][l]];
    return euler[rmq[y-(1<<l)+1][l]];
}
int main()
{
    fin>>n>>m;
    for(int i = 2; i<= n; i++ )
    {
        fin>>x;
        g[x].push_back(i);
    }
    Euler(1,0);
    for(int i = 1; i<= nr; i++ )
    {
        rmq[i][0]=i;
        if(i>1) lg[i]=1+lg[i>>1];
    }
    for(int j = 1; (1<<j) <= nr; j++ )
        for(int i = 1; i+(1<<j)-1 <= nr; i++ )
        {
            if(niv[rmq[i][j-1]] < niv[rmq[i+(1<<(j-1))][j-1]])
                rmq[i][j]=rmq[i][j-1];
            else rmq[i][j]=rmq[i+(1<<(j-1))][j-1];
        }
    for(int i = 1; i<= m; i++ )
    {
        fin >> x >> y;
        fout << Lca(x,y) << '\n';
    }
    fin.close();
    fout.close();
    return 0;
}