Cod sursa(job #877995)

Utilizator ericptsStavarache Petru Eric ericpts Data 13 februarie 2013 18:00:05
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.49 kb
#include <fstream>
#include <vector>

using namespace std;

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

#define maxn 100005
#define pb push_back

int n,m;
int k;
int H[maxn<<1];
int L[maxn<<1];
int first[maxn<<1];
int lg[maxn<<1];
int RMQ[20][maxn];
vector<int> graf[maxn];

void dfs(int nod,int lvl)
{
    H[++k] = nod;
    L[k] = lvl;
    first[nod] = k;
    for(vector<int> :: iterator it = graf[nod].begin(); it != graf[nod].end(); ++ it)
    {
        dfs(*it,lvl+1);

        H[++k] = nod;
        L[k] = lvl;
    }
}

void rmq()
{
    int i,j,x;
    for(i=2;i<=k;++i)
        lg[i] = lg[i>>1]+1;
    for(i=1;i<=k;++i)
        RMQ[0][i]=i;
    for(i=1;(1<<i) < k ; ++ i)
    {
        for(j=1;j + (1 << i) <= k;++j)
        {
            x = 1 << (i-1);
            RMQ[i][j] = RMQ[i-1][j];
            if(L[RMQ[i][j]] > L[RMQ[i-1][j+x]])
                RMQ[i][j] = RMQ[i-1][j+x];
        }
    }
}

int query(int a,int b)
{
    a = first[a];
    b = first[b];
    if(a > b)
        swap(a,b);
    int dif = b - a + 1;
    int len = lg[dif];
    int ret = RMQ[len][a];
    dif -= (1 << len);
    if(L[ret] > L[RMQ[len][a+dif]])
        ret = RMQ[len][a+dif];
    return H[ret];
}

int main()
{
    int i,x,y;
    in >> n >> m;

    for(i=2;i<=n;++i)
    {
        in >> x;
        graf[x].pb(i);
    }
    dfs(1,0);
    rmq();
    while(m--)
    {
        in >> x >> y;
        out << query(x,y) << "\n";
    }
    return 0;
}