Cod sursa(job #1163699)

Utilizator VisuianMihaiMihai Visuian VisuianMihai Data 1 aprilie 2014 16:10:26
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.33 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

vector<int>g[100001];
int euler[2*100001], niv[2*100001], first[100001], rmq[2*100001][20], lg[2*100001];
int n, m, x, y, ind;

inline void Euler(int x, int level)
{
    euler[++ind]=x;
    first[x]=ind;
    niv[ind]=level;
    for(vector<int>::iterator it=g[x].begin(); it<g[x].end(); it++ )
    {
        Euler(*it,level+1);
        euler[++ind]=x;
        niv[ind]=level;
    }
}

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 = 2; i<= ind; i++ )
        lg[i]=1+lg[i>>1];
    for(int i = 1; i<= ind; i++ )
        rmq[i][0]=i;
    for(int j = 1; (1<<j)<=ind; j++ )
        for(int i = 1; i+(1<<j)-1<=ind; 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;
}