Cod sursa(job #1369092)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 2 martie 2015 21:42:51
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.65 kb
#include <cstdio>
#include <vector>

#define Nmax 100005

using namespace std;
int DP[18][Nmax];
int cmin[18][Nmax];
int depth[Nmax];
int N,Q;
vector<vector<int> > G;

void DFS(int k,int deep){
    depth[k] = deep;
    for(vector<int>::iterator it = G[k].begin(); it != G[k].end(); ++it)
        DFS(*it,deep+1);
}

void read()
{
    scanf("%d%d",&N,&Q);
    G.resize(N+1);
    for(int i = 2; i <= N; ++i){
        scanf("%d",&DP[0][i]);
        G[DP[0][i]].push_back(i);
    }
    DFS(1,1);
}

void dynamic()
{
    int li = 0;
    while( (1 <<(li+1)) <= N)
        ++li;
    DP[0][1] = 1;
    for(int i = 1; i <= li; ++i)
        for(int j = 1; j <= N; ++j)
            DP[i][j] = DP[i-1][DP[i-1][j]];
}

int get_ancestor(int k,int lv)
{
    for(int i = 0; lv && i <= 16; ++i)
        if(lv & (1<<i))
        {
            lv ^= (1<<i);
            k = DP[i][k];
        }
    return k;
}

void solve()
{
    int a,b;
    for(int i = 1; i <= Q; ++i)
    {
        scanf("%d%d",&a,&b);
        if(depth[a] < depth[b])
            swap(a,b);
        a = get_ancestor(a,depth[a] - depth[b]);
        if(a == b){
            printf("%d\n",a);
            continue;
        }
        int lim = 0;
        while( (1<<(lim+1)) <= depth[a])
            ++lim;
        for(int j = lim; j >= 0; --j)
            if(DP[j][a] != DP[j][b])
            {
                a = DP[j][a];
                b = DP[j][b];
            }
        printf("%d\n",DP[0][a]);
    }
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

    read();
    dynamic();
    solve();

    return 0;
}