Cod sursa(job #1225682)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 3 septembrie 2014 13:05:04
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.11 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#include <bitset>

#define Nmax 100005
#define DIM 2666013
#define next (++pointer == DIM) ? fread(buffer,1,DIM,stdin),pointer = 0 : 0

char buffer[DIM];
int pointer = DIM - 1;

void scanf(int &A)
{
    A = 0;
    for(;'0'>buffer[pointer]||buffer[pointer]>'9';next);
    for(;'0'<=buffer[pointer]&&buffer[pointer]<='9';next)
        A = A * 10 + buffer[pointer] - 48;
}

using namespace std;

int DP[Nmax][17],N,M;
int depth[Nmax];
vector<int> G[Nmax];

void prepare()
{
    for(int i = 2; i <= N; ++i)
    {
        scanf(DP[i][0]);/// al 2^0 lea stramos a lui i ( tasu )
        G[DP[i][0]].push_back(i);
    }
    DP[1][0] = 1;///el e tatal lui :D
    for(int j = 1; j <= 16; ++j)
        for(int i = 1; i <= N; ++i)
            DP[i][j] = DP[DP[i][j-1]][j-1];
            /// al 2^j-1 lea stramos celui de-al 2^j-1 lea stramos a lui i 2*2^j-1 = 2^j
}

int daddy(int nodc,int niv)
{
    for(int i = 0; niv && i <= 16; ++i)
        if(niv & (1<<i))
        {
            nodc = DP[nodc][i];
            niv ^= (1<<i);
        }
    return nodc;
}

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

void solve()
{
    int a,b;
    DFS(1);
    for(int i = 1; i <= M; ++i)
    {
        scanf(a),scanf(b);
        if(depth[a] < depth[b])
            swap(a,b);
        if(depth[a] != depth[b])
            a = daddy(a,depth[a] - depth[b]);
        int li= 0,lf = N,m;
        if(a == b)
        {
            printf("%d\n",a);
            continue;
        }
        while(DP[a][0] != DP[b][0])
        {
            for(int k = 16; k >= 0; --k)
                if(DP[a][k] != DP[b][k])
                {
                    a = DP[a][k];
                    b = DP[b][k];
                }
        }
        printf("%d\n",DP[a][0]);
    }
}

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

    scanf(N);scanf(M);
    prepare();
    solve();

    return 0;
}